package com.zbkj.crmeb.store.service.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.google.common.cache.CacheBuilder;
import com.utils.*;
import com.utils.dto.StoreProductDto;
import com.utils.dto.StoreProductQueryDto;
import com.zbkj.crmeb.authorization.model.TokenModel;
import com.zbkj.crmeb.merchant.admin.service.StoreProductStockService;
import com.zbkj.crmeb.store.intercept.RateLimiter;
import com.zbkj.crmeb.enums.*;
import com.zbkj.crmeb.store.dto.product.StoreProductQueryDTO;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.request.*;
import com.zbkj.crmeb.store.service.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
import com.common.PageParamRequest;
import com.constants.Constants;
import com.crmeb.core.config.MybatisPlusConfig;
import com.crmeb.core.exception.CrmebException;
import com.crmeb.core.utils.RedisUtil;
import com.crmeb.core.utils.TableNameUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.utils.vo.dateLimitUtilVo;
import com.zbkj.crmeb.chant.model.CategoryMatch;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.model.ChannelProduct;
import com.zbkj.crmeb.chant.request.ChannelProductRequest;
import com.zbkj.crmeb.chant.service.ICategoryMatchService;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.chant.service.IChannelProductService;
import com.zbkj.crmeb.chant.vo.ChannelProductVo;
import com.zbkj.crmeb.export.vo.ProductExcelVo;
import com.zbkj.crmeb.front.request.IndexStoreProductSearchRequest;
import com.zbkj.crmeb.front.request.ProductRequest;
import com.zbkj.crmeb.merchant.api.service.MerProductService;
import com.zbkj.crmeb.store.dao.StoreProductAttrValueDao;
import com.zbkj.crmeb.store.dao.StoreProductDao;
import com.zbkj.crmeb.store.dao.StoreProductNormDao;
import com.zbkj.crmeb.store.response.StoreProductApiResponse;
import com.zbkj.crmeb.store.response.StoreProductAttrValueApiResponse;
import com.zbkj.crmeb.store.response.StoreProductAttrValueResponse;
import com.zbkj.crmeb.store.response.StoreProductNormKeywordResponse;
import com.zbkj.crmeb.store.response.StoreProductNormResponse;
import com.zbkj.crmeb.store.response.StoreProductResponse;
import com.zbkj.crmeb.store.response.StoreProductTabsHeader;
import com.zbkj.crmeb.store.utilService.OrderUtils;
import com.zbkj.crmeb.system.service.SystemAdminService;
import com.zbkj.crmeb.system.service.SystemAttachmentService;
import com.zbkj.crmeb.system.service.SystemConfigService;
import com.zbkj.crmeb.task.order.OrderRefundByUser;
import com.zbkj.crmeb.tools.model.MoneyExchange;
import com.zbkj.crmeb.tools.service.MoneyExchangeService;
import com.google.common.cache.Cache;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import springfox.documentation.annotations.Cacheable;

/**
* @author Mr.Zhang
* @description StoreProductServiceImpl 接口实现
* @date 2020-05-27
*/
@Slf4j
@Service
public class StoreProductServiceImpl extends ServiceImpl<StoreProductDao, StoreProduct> implements StoreProductService {
    @Autowired
    PriceUtil priceUtil;
    @Resource
    private StoreProductDao storeProductDAO;
    @Resource
    private StoreProductNormDao storeProductNormDAO;
    @Resource
    private StoreProductNormService storeProductNormService;
    @Resource
    private StoreProductAttrValueDao storeProductAttrValueDAO;
    @Autowired
    private StoreProductAttrService attrService;
    @Autowired
    private StoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    private StoreProductCateService storeProductCateService;
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private StoreProductDescriptionService storeProductDescriptionService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SystemAttachmentService systemAttachmentService;
    @Autowired
    private StoreProductAttrResultService storeProductAttrResultService;
    @Autowired
    private StoreProductCouponService storeProductCouponService;
    @Autowired
    private StoreBrandService storeBrandService;
    @Autowired
    private IChannelProductService channelProductService;
    @Autowired
    private SupplierService supplierService;
    @Autowired
    OrderUtils orderUtils;
    @Autowired
    ProductUtil productUtil;
    @Autowired
    ICategoryMatchService categoryMatchService;
    @Autowired
    StoreProductMerService storeProductMerService;
    @Autowired
    MerProductService merProductService;
    //@Autowired
    //ProductSearchService productSearchService;
    @Autowired
    private IChannelMerchantService channelMerchantService;
    @Autowired
    private StoreZoneProductService storeZoneProductService;
    @Autowired
    private StoreProductStockService storeProductStockService;
    @Autowired
    private SystemAdminService systemAdminService;
    @Autowired
    StoreProductValueMerService storeProductValueMerService;
    @Autowired
    private StoreProductNormDescriptionService storeProductNormDescriptionService;
    @Autowired
    private MoneyExchangeService moneyExchangeService;
    @Autowired
    private StoreProductAttrService storeProductAttrService;
    @Autowired
    private ProductConvertUtil productConvertUtil;
    @Autowired
    private MarkupRateService markupRateService;
    @Autowired
    private ChannelCategoryConfigService channelCategoryConfigService;
    @Autowired
    private StoreCartService storeCartService;

    private static final Logger logger = LoggerFactory.getLogger(OrderRefundByUser.class);

    /**
     * H5端使用
     * @param request
     * @param pageParamRequest
     * @param productIdList
     * @return
     */
    @Override
    public List<StoreProduct> getList(StoreProductSearchRequest request, PageParamRequest pageParamRequest, List<Integer> productIdList,Integer merId) {
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (request.getIsBest() != null) {
            lambdaQueryWrapper.eq(StoreProduct::getIsBest, request.getIsBest());
        }

        if (request.getIsNew() != null) {
            lambdaQueryWrapper.eq(StoreProduct::getIsNew, request.getIsNew());
        }

        if (request.getIsBenefit() != null) {
            lambdaQueryWrapper.eq(StoreProduct::getIsBest, request.getIsBenefit());
        }

        if (null != productIdList && productIdList.size() > 0) {
            lambdaQueryWrapper.in(StoreProduct::getId, productIdList);
        }

        lambdaQueryWrapper.eq(StoreProduct::getIsDel, false).orderByDesc(StoreProduct::getId);

        if(request.getType() == 1){
            lambdaQueryWrapper.gt(StoreProduct::getStock, 0).eq(StoreProduct::getIsShow, true);
            lambdaQueryWrapper.notInSql(StoreProduct::getId, "SELECT product_id FROM " + TableNameUtil.getProductMerName(merId) + " WHERE is_not_show = 1");
        }else if(request.getType() == 2){
            lambdaQueryWrapper.and(e->e.le(StoreProduct::getStock,0).or().eq(StoreProduct::getIsShow,false).or()
                    .inSql(StoreProduct::getId, "SELECT product_id FROM " + TableNameUtil.getProductMerName(merId) + " WHERE is_not_show = 1"));
        }

        List<StoreProduct> storeProducts = storeProductDAO.selectList(lambdaQueryWrapper);
        // 匹配详情属性(此处应该不需要, 要的话就开启即可 author: daigb)
        // productConvertUtil.convertProduct(storeProducts);
        productConvertUtil.convertProductImage(storeProducts);
        // 加价计算规则
        priceUtil.calcProductPrice(storeProducts, merId,AreaTypeEnum.CN.getType());
        return storeProducts;
    }

    /**
     * 标准商品分页列表
     */
    @Override
    public PageInfo<StoreProductNorm> getNormList(StoreProductSearchRequest request, PageParamRequest pageParamRequest) {
        // 组装条件
        LambdaQueryWrapper<StoreProductNorm> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        if (StringUtils.isNotBlank(request.getCateId())) {
            List<Integer> cateIds = categoryMatchService.getThreeChildVoListByPid(Integer.parseInt(request.getCateId())).stream().map(CategoryMatch::getId).collect(Collectors.toList());
            String cateIdStr = StringUtils.join(cateIds, ",");
            lambdaQueryWrapper.apply(CrmebUtil.getFindInSetSql("cate_id", cateIdStr));
        }
        if(CollectionUtils.isNotEmpty(request.getCateIds())){
            List<Integer> cateIds = new ArrayList<>();
            request.getCateIds().forEach(cateId->cateIds.addAll(categoryMatchService.getThreeChildVoListByPid(cateId).stream().map(CategoryMatch::getId).collect(Collectors.toList())));
            String cateIdStr = StringUtils.join(cateIds, ",");
            lambdaQueryWrapper.apply(CrmebUtil.getFindInSetSql("cate_id", cateIdStr));
        }
        // 关键字搜索
        if (!StringUtils.isBlank(request.getKeywords())) {
            lambdaQueryWrapper.and(i -> i.or().eq(NumberUtil.isInteger(request.getKeywords()),StoreProductNorm :: getId, request.getKeywords()).or().like(StoreProductNorm::getStoreName, request.getKeywords()).or().like(StoreProductNorm::getKeyword, request.getKeywords()).or().like(StoreProductNorm::getBarCode, request.getKeywords()));
        }
        if (StringUtils.isNotBlank(request.getBrandId())) {
            lambdaQueryWrapper.eq(StoreProductNorm :: getBrandId, request.getBrandId());
        }
        if(CollectionUtils.isNotEmpty(request.getBrandIds())){
            lambdaQueryWrapper.in(StoreProductNorm::getBrandId,request.getBrandIds());
        }
        if (null != request.getProductCount()) {
            lambdaQueryWrapper.eq(StoreProductNorm :: getProductCount, request.getProductCount());
        }
        if (ObjectUtils.isNotNull(request.getCreateTimeStart()) && ObjectUtils.isNotNull(request.getCreateTimeEnd())){
            lambdaQueryWrapper.between(StoreProductNorm :: getCreateTime,request.getCreateTimeStart(),request.getCreateTimeEnd());
        }
        if (ObjectUtils.isNotNull(request.getUpdateTimeStart()) && ObjectUtils.isNotNull(request.getUpdateTimeEnd())){
            lambdaQueryWrapper.between(StoreProductNorm :: getUpdateTime,request.getUpdateTimeStart(),request.getUpdateTimeEnd());
        }
        if (null != request.getSeasonCode()) {
        	lambdaQueryWrapper.likeRight(StoreProductNorm :: getSeasonCode, request.getSeasonCode());
        }
        lambdaQueryWrapper.orderByDesc(StoreProductNorm :: getId);

        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<StoreProductNorm> storeProducts = storeProductNormDAO.selectList(lambdaQueryWrapper);
        PageInfo<StoreProductNorm> pageInfo = PageInfo.of(storeProducts);

        return pageInfo;
    }

    @Override
    public Boolean saveNormProduct(Integer productId) {
        StoreProduct storeProduct = storeProductDAO.selectById(productId);
        // 匹配详情属性
        productConvertUtil.convertProduct(storeProduct);
//        storeProduct.setId(null);

        StoreProductNorm storeProductNorm = new StoreProductNorm();
        StoreProductNorm norm = storeProductNormDAO.selectOne(Wrappers.<StoreProductNorm>lambdaQuery()
                .eq(StoreProductNorm :: getKeyword, storeProduct.getKeyword())
                .last("LIMIT 1")
                );
        BeanUtils.copyProperties(storeProduct, storeProductNorm);
        storeProductNorm.setId(null);
        if(null != norm) {
            storeProductNorm.setId(norm.getId());
        }
        storeProductNormService.saveOrUpdate(storeProductNorm);

        return this.update(Wrappers.<StoreProduct>lambdaUpdate()
                .eq(StoreProduct :: getId, storeProduct.getId())
                .set(StoreProduct :: getNormId, storeProductNorm.getId())
                );
    }

    /**
     * 列表
     * @param request 请求参数
     * @param pageParamRequest 分页类参数
     * @author Mr.Zhang
     * @since 2020-05-27
     * @return List<StoreProduct>
     */
    @Override
    @RateLimiter(qps = 8, timeout = 1, timeUnit = TimeUnit.SECONDS)
    public PageInfo<StoreProductResponse> getList(StoreProductSearchRequest request, PageParamRequest pageParamRequest) {
        //带 StoreProduct 类的多条件查询
        LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = getQueryWrapper(request);
        Page<StoreProduct> storeProductPage = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<StoreProduct> storeProducts = storeProductDAO.selectList(lambdaQueryWrapper);
        if(CollectionUtils.isEmpty(storeProducts)) {
            return CommonPage.copyPageInfo(storeProductPage, new ArrayList<>());
        }
        // 匹配详情属性(只在活动列表里面查询)
        if(BooleanUtil.isTrue(request.getMerUse())) {
        	productConvertUtil.convertProduct(storeProducts);
        } else {
            productConvertUtil.convertProductImage(storeProducts);
        }
        List<Integer> normIdList = storeProducts.stream().map(StoreProduct::getNormId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        Map<Integer, String> normMap = new HashMap<>();
        if(CollectionUtils.isNotEmpty(normIdList)){
            List<StoreProductNorm> productNormList = storeProductNormService.list(Wrappers.<StoreProductNorm>lambdaQuery().in(StoreProductNorm::getId, normIdList));
            normMap = productNormList.stream().collect(Collectors.toMap(StoreProductNorm::getId, StoreProductNorm::getKeyword));
        }
        /******** 查询对应属性表数据(弃用循环查询, 优化搜索速度) author: daigb ********/
        List<Integer> ids = storeProducts.stream().map(p -> p.getId()).collect(Collectors.toList());
        // 处理attrvalue数据
        List<StoreProductAttrValue> attrValues = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery()
                .in(StoreProductAttrValue :: getProductId, ids)
                );
        storeProductStockService.showStockBatch(attrValues);
        Map<Integer, List<StoreProductAttrValueResponse>> attrValueMap = attrValues.stream().collect(Collectors.toMap(StoreProductAttrValue :: getProductId,
                s ->  {
                    List<StoreProductAttrValueResponse> list = new ArrayList<StoreProductAttrValueResponse>();
                    StoreProductAttrValueResponse response = new StoreProductAttrValueResponse();
                    BeanUtils.copyProperties(s, response);
                    list.add(response);
                    return list;
                },
                (List<StoreProductAttrValueResponse> value1, List<StoreProductAttrValueResponse> value2) -> {
                    value1.addAll(value2);
                    return value1;
                }
                ));

        // 循环赋值
        List<StoreProductResponse> storeProductResponses = new ArrayList<>();
        for(StoreProduct product : storeProducts) {
            Integer id = product.getId();
            StoreProductResponse storeProductResponse = new StoreProductResponse();
            BeanUtils.copyProperties(product, storeProductResponse);
            storeProductResponse.setAttrValue(attrValueMap.get(id));
            // 通过原价算折扣率 ----处理
            if (storeProductResponse.getOtPrice() != null && storeProductResponse.getOtPrice().intValue() > 0) {
                BigDecimal bigDecimal = priceUtil.calcDiscount(storeProductResponse.getSourceCost(), storeProductResponse.getOtPrice(), storeProductResponse.getExchangeRate());
                if (null != bigDecimal) {
                    storeProductResponse.setDiscount(bigDecimal.toString() + "折");
                }
            }
            //设置销售状态库存小于0售罄，大于0上架为在售，下架为仓库中
            storeProductResponse.setSalesStatus(storeProductResponse.getStock() > 0 ? (storeProductResponse.getIsShow() ? 1 : 0) :  2);
            storeProductResponse.setNormKeywords(normMap.get(product.getNormId()));
            storeProductResponses.add(storeProductResponse);
        }
        /******** end *******/

        return CommonPage.copyPageInfo(storeProductPage, storeProductResponses);
    }

    /**
     * 列表
     * @param request 请求参数
     * @param pageParamRequest 分页类参数
     * @author Mr.Zhang
     * @since 2020-05-27
     * @return List<StoreProduct>
     */
    @Override
    public PageInfo<StoreProductResponse> getListV2(StoreProductSearchRequest request, PageParamRequest pageParamRequest) {
        long a = System.currentTimeMillis();

        //带 StoreProduct 类的多条件查询
        StoreProductQueryDto queryDto = getStoreProductQueryV2(request);
        Page<StoreProduct> storeProductPage = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        log.info("商户查询商品列表sql参数:{}", JSON.toJSONString(queryDto));
        List<StoreProduct> storeProducts = storeProductDAO.queryProductListV2(queryDto);



        if(CollectionUtils.isEmpty(storeProducts)) {
            return CommonPage.copyPageInfo(storeProductPage, new ArrayList<>());
        }
        // 匹配详情属性(只在活动列表里面查询)
        if(BooleanUtil.isTrue(request.getMerUse())) {
            productConvertUtil.convertProduct(storeProducts);
        } else {
            productConvertUtil.convertProductImage(storeProducts);
        }
        List<Integer> normIdList = storeProducts.stream().map(StoreProduct::getNormId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        Map<Integer, String> normMap = new HashMap<>();
        if(CollectionUtils.isNotEmpty(normIdList)){
            List<StoreProductNorm> productNormList = storeProductNormService.list(Wrappers.<StoreProductNorm>lambdaQuery().in(StoreProductNorm::getId, normIdList));
            normMap = productNormList.stream().collect(Collectors.toMap(StoreProductNorm::getId, StoreProductNorm::getKeyword));
        }
        /******** 查询对应属性表数据(弃用循环查询, 优化搜索速度) author: daigb ********/
        List<Integer> ids = storeProducts.stream().map(p -> p.getId()).collect(Collectors.toList());
        // 处理attrvalue数据
        List<StoreProductAttrValue> attrValues = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery()
                .in(StoreProductAttrValue :: getProductId, ids)
        );
        for(StoreProductAttrValue attrValue : attrValues){
            if (attrValue != null && attrValue.getGroupStock() != null && attrValue.getGroupStock() > 0) {
                attrValue.setStock(attrValue.getStock() + attrValue.getGroupStock());
            }
        }
        Map<Integer, List<StoreProductAttrValueResponse>> attrValueMap = attrValues.stream().collect(Collectors.toMap(StoreProductAttrValue :: getProductId,
                s ->  {
                    List<StoreProductAttrValueResponse> list = new ArrayList<StoreProductAttrValueResponse>();
                    StoreProductAttrValueResponse response = new StoreProductAttrValueResponse();
                    BeanUtils.copyProperties(s, response);
                    list.add(response);
                    return list;
                },
                (List<StoreProductAttrValueResponse> value1, List<StoreProductAttrValueResponse> value2) -> {
                    value1.addAll(value2);
                    return value1;
                }
        ));

        // 循环赋值
        List<StoreProductResponse> storeProductResponses = new ArrayList<>();
        for(StoreProduct product : storeProducts) {
            Integer id = product.getId();
            StoreProductResponse storeProductResponse = new StoreProductResponse();
            BeanUtils.copyProperties(product, storeProductResponse);
            storeProductResponse.setAttrValue(attrValueMap.get(id));
            // 通过原价算折扣率 ----处理
            if (storeProductResponse.getOtPrice() != null && storeProductResponse.getOtPrice().intValue() > 0) {
                BigDecimal bigDecimal = priceUtil.calcDiscount(storeProductResponse.getSourceCost(), storeProductResponse.getOtPrice(), storeProductResponse.getExchangeRate());
                if (null != bigDecimal) {
                    storeProductResponse.setDiscount(bigDecimal.toString() + "折");
                }
            }
            //设置销售状态库存小于0售罄，大于0上架为在售，下架为仓库中
            storeProductResponse.setSalesStatus(storeProductResponse.getStock() > 0 ? (storeProductResponse.getIsShow() ? 1 : 0) :  2);
            storeProductResponse.setNormKeywords(normMap.get(product.getNormId()));
            storeProductResponses.add(storeProductResponse);
        }
        /******** end *******/
        long b = System.currentTimeMillis();
        log.info("供应商商品查询方式二新版，耗时：{}",  (b - a));
        return CommonPage.copyPageInfo(storeProductPage, storeProductResponses);
    }

    /**
     * 根据商品id集合获取
     * @param productIds id集合
     * @return
     */
    @Override
    public List<StoreProduct> getListInIds(List<Integer> productIds) {
        LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(StoreProduct::getId, productIds);
        List<StoreProduct> storeProducts = storeProductDAO.selectList(lambdaQueryWrapper);
        // 匹配详情属性(此处应该不需要, 要的话就开启即可 author: daigb)
        // productConvertUtil.convertProduct(storeProducts);
        productConvertUtil.convertProductImage(storeProducts);

        return storeProducts;
    }

    /**
     * 根据商品id集合获取
     * @param productIds id集合
     * @return
     */
    @Override
    public List<Integer> listProductIdByStoreName(String productName) {
        LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(StoreProduct::getStoreName, productName);
        lambdaQueryWrapper.select(StoreProduct::getId);
        List<StoreProduct> storeProducts = storeProductDAO.selectList(lambdaQueryWrapper);
        if(CollectionUtils.isEmpty(storeProducts)){
            return new ArrayList<>();
        }
        return storeProducts.stream().map(StoreProduct::getId).distinct().collect(Collectors.toList());
    }

    /**
     * 根据产品属性查询
     * @param storeProduct 产品参数
     * @return 产品结果
     */
    @Override
    public StoreProduct getByEntity(StoreProduct storeProduct) {
        LambdaQueryWrapper<StoreProduct> lqw = new LambdaQueryWrapper<>();
        lqw.setEntity(storeProduct);
        StoreProduct dbStoreProduct = storeProductDAO.selectOne(lqw);
        // 匹配详情属性
        productConvertUtil.convertProduct(dbStoreProduct);

        return dbStoreProduct;
    }

    /**
     * 新增产品
     * @param storeProductRequest 新增产品request对象
     * @return 新增结果
     */
    @Override
    public boolean save(StoreProductRequest storeProductRequest) {
        if (!redisUtil.lock(RedisUtil.PRODUCT_BARCODE_LOCK, "product", 1L)) {
            return false;
        }
        //设置barCode
        StoreBrand storeBrand = storeBrandService.getById(storeProductRequest.getBrandId());
        storeProductRequest.setBarCode(getProductBarCode());
        StoreProduct storeProduct = new StoreProduct();
        BeanUtils.copyProperties(storeProductRequest, storeProduct);
        storeProduct.setIsShow(true);
        storeProduct.setCreateTime(new Date());
        if(null!=storeBrand){
            storeProduct.setBrandName(storeBrand.getEnName());
        }
        //主图
        storeProduct.setImage(systemAttachmentService.clearPrefix(storeProduct.getImage()));

        //轮播图
        storeProduct.setSliderImage(systemAttachmentService.clearPrefix(storeProduct.getSliderImage()));

        // 获取 attrValue 字符串 解析后对应attrValue表中的数据
        //        List<StoreProductAttrValueRequest> storeProductAttrValuesRequest = getStoreProductAttrValueRequests(storeProductRequest);

        //计算价格
        calcPriceForAttrValues(storeProductRequest, storeProduct);

        //保存数据
        storeProduct.setIsEurope(ProductTypeEnum.INSIDE.getCode());
        Supplier supplier =  supplierService.getById(storeProductRequest.getSuppliersId());
        if(null!=supplier){
            storeProduct.setSuppliersName(supplier.getSuppliersName());
        }
        boolean save = save(storeProduct);
        redisUtil.unlock(RedisUtil.PRODUCT_BARCODE_LOCK);
        if (null != storeProduct.getId()) {
            storeProductRequest.setId(storeProduct.getId());
        }
        if (storeProductRequest.getSpecType()) { // 多属性
            storeProductRequest.getAttr().forEach(e -> {
                e.setProductId(storeProduct.getId());
                e.setAttrValues(StringUtils.strip(e.getAttrValues().replace("\"", ""), "[]"));
                e.setBarCode(storeProduct.getBarCode());
            });
            boolean attrAddResult = attrService.saveBatch(storeProductRequest.getAttr());
            if (!attrAddResult)
                throw new CrmebException("新增属性名失败");
        } else { // 单属性
            StoreProductAttr singleAttr = new StoreProductAttr();
            singleAttr.setProductId(storeProduct.getId()).setAttrName("规格").setAttrValues("默认").setType(0);
            singleAttr.setBarCode(storeProduct.getBarCode());
            boolean attrAddResult = attrService.save(singleAttr);
            if (!attrAddResult)
                throw new CrmebException("新增属性名失败");
            StoreProductAttrValue singleAttrValue = new StoreProductAttrValue();
            BigDecimal commissionL1 = BigDecimal.ZERO;
            BigDecimal commissionL2 = BigDecimal.ZERO;
            if (storeProductRequest.getAttrValue().size() > 0) {
                commissionL1 = null != storeProductRequest.getAttrValue().get(0).getBrokerage() ? storeProductRequest.getAttrValue().get(0).getBrokerage() : BigDecimal.ZERO;
                commissionL2 = null != storeProductRequest.getAttrValue().get(0).getBrokerageTwo() ? storeProductRequest.getAttrValue().get(0).getBrokerageTwo() : BigDecimal.ZERO;
            }

            singleAttrValue.setProductId(storeProduct.getId()).setStock(storeProduct.getStock()).setSuk("默认").setSales(storeProduct.getSales()).setPrice(storeProduct.getPrice()).setImage(systemAttachmentService.clearPrefix(storeProduct.getImage())).setCost(storeProduct.getCost()).setBarCode(storeProduct.getBarCode()).setOtPrice(storeProduct.getOtPrice()).setBrokerage(commissionL1).setBrokerageTwo(commissionL2);
            singleAttrValue.setBarCode(storeProduct.getBarCode());
            boolean saveOrUpdateResult = storeProductAttrValueService.save(singleAttrValue);
            if (!saveOrUpdateResult)
                throw new CrmebException("新增属性详情失败");
        }
        if (null != storeProductRequest.getAttrValue() && storeProductRequest.getAttrValue().size() > 0) {
            // 批量设置attrValues对象的商品id
            List<StoreProductAttrValueRequest> storeProductAttrValuesRequest = storeProductRequest.getAttrValue();
            storeProductAttrValuesRequest.forEach(e -> {
                e.setProductId(storeProduct.getId());
            });
            List<StoreProductAttrValue> storeProductAttrValues = new ArrayList<>();
            for (StoreProductAttrValueRequest attrValuesRequest : storeProductAttrValuesRequest) {
                StoreProductAttrValue spav = new StoreProductAttrValue();
                BeanUtils.copyProperties(attrValuesRequest, spav);
                //设置sku字段
                if (null == attrValuesRequest.getAttrValue()) {
                    break;
                }
                List<String> skuList = new ArrayList<>();
                for (Map.Entry<String, String> vo : attrValuesRequest.getAttrValue().entrySet()) {
                    skuList.add(vo.getValue());
                    spav.setSuk(String.join(",", skuList));
                    //                    HashMap<String, Object> attrValues = setAttrValueByRequest(storeProductRequest);
                }
                spav.setImage(systemAttachmentService.clearPrefix(spav.getImage()));
                spav.setAttrValue(JSON.toJSONString(attrValuesRequest.getAttrValue()));
                spav.setBarCode(storeProduct.getBarCode());
                storeProductAttrValues.add(spav);
            }
            // 保存属性
            if (storeProductAttrValues.size() > 0) {
                boolean saveOrUpdateResult = storeProductAttrValueService.saveBatch(storeProductAttrValues);
                StoreProductAttrResult attrResult = new StoreProductAttrResult(/*0, */storeProduct.getId(), systemAttachmentService.clearPrefix(JSON.toJSONString(storeProductRequest.getAttrValue())), DateUtil.getNowTime(), Constants.PRODUCT_TYPE_NORMAL, storeProductRequest.getBarCode());
                attrResult.setBarCode(storeProduct.getBarCode());
                storeProductAttrResultService.save(attrResult);
                if (!saveOrUpdateResult)
                    throw new CrmebException("新增属性详情失败");
            }
        }
        // 处理富文本
        StoreProductDescription spd = StoreProductDescription.getDescriptionByProduct(storeProduct);
        spd.setProductId(storeProduct.getId());
        storeProductDescriptionService.save(spd);

        // 处理优惠券关联信息
        shipProductCoupons(storeProductRequest, storeProduct);
        return save;
    }

    /**
     * 更新产品
     * @param storeProductRequest 更新产品request对象
     * @return 更新结果
     */
    @Override
    public boolean update(StoreProductRequest storeProductRequest) {
        StoreProduct storeProduct = new StoreProduct();
        BeanUtils.copyProperties(storeProductRequest, storeProduct);
        storeProduct.setCreateTime(new Date());
        //主图
        storeProduct.setImage(systemAttachmentService.clearPrefix(storeProduct.getImage()));

        //轮播图
        storeProduct.setSliderImage(systemAttachmentService.clearPrefix(storeProduct.getSliderImage()));

        StoreBrand storeBrand = storeBrandService.getById(storeProduct.getBrandId());
        if(null!=storeBrand){
            storeProduct.setBrandName(storeBrand.getEnName());
        }
        //        List<StoreProductAttrValueRequest> storeProductAttrValuesRequest = getStoreProductAttrValueRequests(storeProductRequest);

        calcPriceForAttrValues(storeProductRequest, storeProduct);
        if(null!=storeProductRequest.getSuppliersId()){
            Supplier supplier =  supplierService.getById(storeProductRequest.getSuppliersId());
            if(null!=supplier){
                storeProduct.setSuppliersName(supplier.getSuppliersName());
            }
        }
        int saveCount = storeProductDAO.updateById(storeProduct);
        // 对attr表做全量更新，删除原有数据保存现有数据
        attrService.removeByProductId(storeProduct.getId());
        // 查出所有的sku属性,用suk找到相同的属性,做更新
        //        storeProductAttrValueService.removeByProductId(storeProduct.getId());
        List<StoreProductAttrValue> attrValuelist = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery().eq(StoreProductAttrValue::getProductId, storeProduct.getId()));
        Map<String, StoreProductAttrValue> attrValueMap = attrValuelist == null ? MapUtil.newHashMap() : attrValuelist.stream().collect(Collectors.toMap(StoreProductAttrValue::getSuk, Function.identity()));
        Map<String, StoreProductAttrValue> oldAttrValueMap = attrValuelist == null ? MapUtil.newHashMap() : attrValuelist.stream().collect(Collectors.toMap(StoreProductAttrValue::getSourceSkuId, Function.identity()));
        if (CollectionUtils.isNotEmpty(storeProductRequest.getAttrValue())) {
            storeProductRequest.getAttrValue().forEach(attrValueRequest -> {
                if (null != attrValueRequest.getAttrValue()) {
                    List<String> skuList = new ArrayList<>();
                    for (Map.Entry<String, String> vo : attrValueRequest.getAttrValue().entrySet()) {
                        skuList.add(vo.getValue());
                    }
                    attrValueRequest.setSuk(String.join(",", skuList));
//                    attrValueRequest.setId(attrValueMap.containsKey(attrValueRequest.getSuk()) ? attrValueMap.get(attrValueRequest.getSuk()).getId() : null);
                }
            });
        }

        StoreProduct product = storeProductDAO.selectById(storeProductRequest.getId());

        if (storeProductRequest.getSpecType()) { // todo 确认单属性商品的attr参数
            storeProductRequest.getAttr().forEach(e -> {
                e.setProductId(storeProductRequest.getId());
                e.setAttrValues(StringUtils.strip(e.getAttrValues().replace("\"", ""), "[]"));
            });
            attrService.saveBatch(storeProductRequest.getAttr());
            if (CollectionUtils.isNotEmpty(storeProductRequest.getAttrValue())) {
                storeProductAttrValueService.removeByProductId(storeProductRequest.getId());
                List<StoreProductAttrValueRequest> storeProductAttrValuesRequest = storeProductRequest.getAttrValue();
                // 批量设置attrValues对象的商品id
                storeProductAttrValuesRequest.forEach(e -> e.setProductId(storeProductRequest.getId()));
                List<StoreProductAttrValue> storeProductAttrValues = new ArrayList<>();
                for (StoreProductAttrValueRequest attrValuesRequest : storeProductAttrValuesRequest) {
                    StoreProductAttrValue spav = new StoreProductAttrValue();

                    BeanUtils.copyProperties(attrValuesRequest, spav);
                    // 设置id
                    //设置sku字段
                    //                    if(null != attrValuesRequest.getAttrValue()){
                    //                        List<String> skuList = new ArrayList<>();
                    //                        for(Map.Entry<String,String> vo: attrValuesRequest.getAttrValue().entrySet()){
                    //                            skuList.add(vo.getValue());
                    //                        }
                    //                        spav.setSuk(String.join(",",skuList));
                    //                    }
                    //                    HashMap<String, Object> attrValues = setAttrValueByRequest(storeProductRequest);
                    spav.setAttrValue(JSON.toJSONString(attrValuesRequest.getAttrValue()));
                    //                    spav.setAttrValue(JSON.toJSONString(attrValues));
                    spav.setBarCode(product.getBarCode());

                    String sourceSkuId = spav.getSourceSkuId();
                    StoreProductAttrValue oldAttrValue = oldAttrValueMap.get(sourceSkuId);
                    storeProductStockService.editStock(spav, oldAttrValue);

                    storeProductAttrValues.add(spav);
                }
                boolean saveOrUpdateResult = storeProductAttrValueService.saveBatch(storeProductAttrValues);
                // attrResult整存整取，不做更新
                storeProductAttrResultService.deleteByProductId(storeProduct.getId());
                StoreProductAttrResult attrResult = new StoreProductAttrResult(/*0, */storeProduct.getId(), systemAttachmentService.clearPrefix(JSON.toJSONString(storeProductRequest.getAttrValue())), DateUtil.getNowTime(), Constants.PRODUCT_TYPE_NORMAL, storeProduct.getBarCode());
                storeProductAttrResultService.save(attrResult);
                if (!saveOrUpdateResult)
                    throw new CrmebException("编辑属性详情失败");

            }
        } else {
            StoreProductAttr singleAttr = new StoreProductAttr();
            singleAttr.setProductId(storeProduct.getId()).setAttrName("规格").setAttrValues("默认").setType(0);
            boolean attrAddResult = attrService.save(singleAttr);
            if (!attrAddResult)
                throw new CrmebException("新增属性名失败");
            StoreProductAttrValue singleAttrValue = new StoreProductAttrValue();
            if (storeProductRequest.getAttrValue().size() == 0)
                throw new CrmebException("attrValue不能为空");
            StoreProductAttrValueRequest attrValueRequest = storeProductRequest.getAttrValue().get(0);
            BeanUtils.copyProperties(attrValueRequest, singleAttrValue);
            singleAttrValue.setProductId(storeProduct.getId());
            singleAttrValue.setSuk("默认");
            singleAttrValue.setImage(systemAttachmentService.clearPrefix(singleAttrValue.getImage()));
            singleAttrValue.setBarCode(product.getBarCode());
            String sourceSkuId = singleAttrValue.getSourceSkuId();
            if(null != sourceSkuId) {
                StoreProductAttrValue oldAttrValue = oldAttrValueMap.get(sourceSkuId);
                storeProductStockService.editStock(singleAttrValue, oldAttrValue);

            }
            storeProductAttrValueService.removeByProductId(storeProductRequest.getId());
            boolean saveOrUpdateResult = storeProductAttrValueService.save(singleAttrValue);
            if (!saveOrUpdateResult)
                throw new CrmebException("新增属性详情失败");
        }

        // 处理分类辅助表
        if (null != storeProductRequest.getCateIds()) {
            for (int i = 0; i < storeProductRequest.getCateIds().size(); i++) {
                Integer cateid = storeProductRequest.getCateIds().get(i);
                StoreProductCate storeProductCate = new StoreProductCate(storeProduct.getId(), cateid, DateUtil.getNowTime());
                LambdaUpdateWrapper<StoreProductCate> luw = new LambdaUpdateWrapper<>();
                luw.set(StoreProductCate::getProductId, storeProductCate.getProductId());
                luw.set(StoreProductCate::getCateId, storeProductCate.getCateId());
                luw.set(StoreProductCate::getAddTime, storeProductCate.getAddTime());
                storeProductCateService.update(luw);
                //                if(!updateResult) throw new CrmebException("编辑产品分类辅助失败");
            }
        }

        // 处理富文本
        StoreProductDescription dbDescription = storeProductDescriptionService.getOne(Wrappers.<StoreProductDescription>lambdaQuery()
        		.eq(StoreProductDescription :: getProductId, storeProduct.getId())
        		.last("LIMIT 1")
        		);
        StoreProductDescription storeProductDescription = StoreProductDescription.getDescriptionByRequest(storeProductRequest);
        storeProductDescription.setId(ObjectUtil.isNotNull(dbDescription) ? dbDescription.getId() : null);
        storeProductDescription.setProductId(storeProduct.getId());
        storeProductDescriptionService.saveOrUpdate(storeProductDescription);

        // 处理优惠券关联信息
        shipProductCoupons(storeProductRequest, storeProduct);
        return saveCount > 0;
    }

    /**
     * 批量上架/下架
     * @param vo
     * @return
     */
    @Override
    public Boolean batchEnabled(BatchEnabledRequest vo) {
        boolean isShow = Integer.valueOf(vo.getIsNotShow()) == 1;
        vo.getProductIdList().forEach(e -> {
            StoreProduct storeProduct = this.getById(e)
                    .setId(e)
                    .setIsShow(!isShow)
                    .setTmall(isShow);
            if (this.updateById(storeProduct)) {
                storeCartService.productStatusNotEnable(e);
                //处理品牌-在线商品数量
                storeBrandService.showProductCount(storeProduct.getBrandId(), !isShow);
                //更新关联的渠道商品
                channelProductService.updateProductByBarCode(storeProduct.getBarCode());
            }
        });
        return true;
    }

    /**
     * 验证Barcode
     *
     * @param barCode
     */
    @Override
    public boolean verifyBarCode(String barCode) {
        LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreProduct::getBarCode, barCode);
        return storeProductDAO.selectCount(lambdaQueryWrapper) > 0;
    }

    @Override
    public StoreProductNormResponse getSupplierByProductId(int id) {
        StoreProductNormResponse response = new StoreProductNormResponse();
        StoreProduct product = storeProductDAO.selectById(id);
        Integer normId = product.getNormId();
        if(null != normId) {
            response.setProductNorm(storeProductNormDAO.selectById(normId));
            response.setProducts(listByNormId(normId));
            String description = storeProductNormDescriptionService.getProductNormDesc(id);
            if (Objects.nonNull(response.getProductNorm()) && StringUtils.isNotBlank(description)) {
                response.getProductNorm().setStoreInfo(description);
            }
        } else {
            StoreProductResponse storeProductResponse = getByProductId(id);
            List<StoreProductResponse> storeProductResponses = Arrays.asList(storeProductResponse);
            response.setProducts(storeProductResponses);

            // 使用自建商品属性赋值到标准商品上
            if(CollectionUtils.isNotEmpty(storeProductResponses)) {
                StoreProductNorm norm = new StoreProductNorm();
                BeanUtils.copyProperties(storeProductResponses.get(0), norm);
                response.setProductNorm(norm);
            }
        }

        return response;
    }

    @Override
    public StoreProductNormResponse getSupplierByNormId(int id) {
        StoreProductNormResponse response = new StoreProductNormResponse();
        response.setProductNorm(storeProductNormDAO.selectById(id));
        response.setProducts(listByNormId(id));

        String description = storeProductNormDescriptionService.getProductNormDesc(id);
        if (Objects.nonNull(response.getProductNorm()) && StringUtils.isNotBlank(description)) {
            response.getProductNorm().setStoreInfo(description);
        }
        return response;
    }

    private List<StoreProductResponse> listByNormId(int id) {
        List<StoreProduct> storeProducts = storeProductDAO.selectList(Wrappers.<StoreProduct>lambdaQuery()
                .eq(StoreProduct :: getNormId, id)
                .eq(StoreProduct :: getIsDel, false)
                );
        if (CollectionUtils.isEmpty(storeProducts)) {
            return null;
        }
        // 匹配详情属性
        productConvertUtil.convertProduct(storeProducts);
        List<StoreProductResponse> storeProductResponses = new ArrayList<>();
        for(StoreProduct storeProduct : storeProducts) {
            StoreProductResponse storeProductResponse = new StoreProductResponse();
            BeanUtils.copyProperties(storeProduct, storeProductResponse);
            // 暂写死固定自营小程序私域图权限
            List<Integer> merIds = systemAdminService.getAdminMerIds();
    		if (CollectionUtils.isNotEmpty(merIds) && !merIds.contains(18) && !merIds.contains(30) /* && 45 != merId && 47 != merId*/) {
            	storeProductResponse.setMt(null);
            	storeProductResponse.setSp2(null);
            }
            storeProductResponse.setStockArea(StockAreaTempEnum.getByTempId(storeProduct.getTempId()).getStockAreaCode());
            //发货时间
            storeProductResponse.setDeliveryTime(productUtil.getDeliveryTimeByTempId(storeProduct.getTempId(),storeProduct.getIsEurope(),storeProduct.getMerId(),storeProduct.getId()));
            //收货时间
            String receivingTime = productUtil.getReceivingTime(storeProductResponse.getStockArea(), storeProductResponse.getIsEurope(),storeProduct.getMerId(),storeProduct.getId());
            storeProductResponse.setReceivingTime(receivingTime);
            // 设置sku属性
            storeProductResponse.setAttr(attrService.getByProductId(storeProduct.getId()));
            List<StoreProductAttrValue> storeProductAttrValues = storeProductAttrValueService.getListByProductId(storeProduct.getId());
            if (CollectionUtils.isEmpty(storeProductAttrValues)) {
                continue;
            }

            if (storeProductResponse.getPrice() == null || storeProductResponse.getOtPrice() == null) {
                calcPriceForAttrValues(storeProductAttrValues, storeProductResponse);
            }
            // 根据attrValue生成前端所需的数据
            List<HashMap<String, Object>> attrValues = new ArrayList<>();
            Map<String, StoreProductAttrValue> valMap = new HashMap<>();
            for(StoreProductAttrValue spav : storeProductAttrValues) {
                valMap.put(spav.getAttrValue(), spav);
            }
            if (storeProduct.getSpecType()) {
                // 后端多属性用于编辑
                StoreProductAttrResult attrResult = storeProductAttrResultService.getByProductId(storeProduct.getId());
                //PC 端生成skuAttrInfo
                List<StoreProductAttrValueRequest> storeProductAttrValueRequests = com.alibaba.fastjson.JSONObject.parseArray(attrResult.getResult(), StoreProductAttrValueRequest.class);
                if (null != storeProductAttrValueRequests) {
                    for (int i = 0; i < storeProductAttrValueRequests.size(); i++) {
                        StoreProductAttrValueRequest storeProductAttrValueRequest = storeProductAttrValueRequests.get(i);
                        StoreProductAttrValue attrVal = valMap.get(JSON.toJSONString(storeProductAttrValueRequest.getAttrValue()));
                        if(null == attrVal) {
                            continue;
                        }
                        HashMap<String, Object> attrValue = new HashMap<>();
                        attrValue.put("image", storeProductAttrValueRequest.getImage());
                        attrValue.put("cost", storeProductAttrValueRequest.getCost());
                        attrValue.put("price", storeProductAttrValueRequest.getPrice());
                        attrValue.put("otPrice", storeProductAttrValueRequest.getOtPrice());
                        // 不能显示result里的库存
                        attrValue.put("stock", attrVal.getStock());
                        attrValue.put("barCode", storeProductAttrValueRequest.getBarCode());
                        attrValue.put("weight", storeProductAttrValueRequest.getWeight());
                        attrValue.put("volume", storeProductAttrValueRequest.getVolume());
                        attrValue.put("suk", attrVal.getSuk());
                        attrValue.put("attrValue", JSON.parse(attrVal.getAttrValue()));
                        attrValue.put("brokerage", storeProductAttrValueRequest.getBrokerage());
                        attrValue.put("brokerage_two", storeProductAttrValueRequest.getBrokerageTwo());
                        Iterator<Map.Entry<String, String>> iterator = storeProductAttrValueRequest.getAttrValue().entrySet().iterator();
                        int j = 0;
                        while (iterator.hasNext()) {
                            Map.Entry<String, String> entry = iterator.next();
                            attrValue.put("value" + j, entry.getValue());
                            j += 1;
                        }
                        attrValues.add(attrValue);
                    }
                }
            }

            // H5 端用于生成skuList
            List<StoreProductAttrValueResponse> sPAVResponses = new ArrayList<>();
            for (StoreProductAttrValue storeProductAttrValue : storeProductAttrValues) {
                StoreProductAttrValueResponse atr = new StoreProductAttrValueResponse();
                BeanUtils.copyProperties(storeProductAttrValue, atr);
                sPAVResponses.add(atr);
            }

            storeProductResponse.setAttrValues(attrValues);
            storeProductResponse.setAttrValue(sPAVResponses);

            storeProductResponses.add(storeProductResponse);
        }

        return storeProductResponses;
    }

    /**
     * 商品详情
     * @param id 商品id
     * @return 详情数据
     */
    @Override
    public StoreProductResponse getByProductId(int id) {
        StoreProduct storeProduct = storeProductDAO.selectById(id);
        if (null == storeProduct) {
            throw new CrmebException("未找到对应商品信息");
        }
        // 匹配详情属性
        productConvertUtil.convertProduct(storeProduct);

        StoreProductResponse storeProductResponse = new StoreProductResponse();
        BeanUtils.copyProperties(storeProduct, storeProductResponse);
        // 暂写死固定自营小程序私域图权限
        List<Integer> merIds = systemAdminService.getAdminMerIds();
		if (CollectionUtils.isNotEmpty(merIds) && !merIds.contains(18) && !merIds.contains(30) /* && 45 != merId && 47 != merId*/) {
        	storeProductResponse.setMt(null);
        	storeProductResponse.setSp2(null);
        }

        storeProductResponse.setStockArea(StockAreaTempEnum.getByTempId(storeProduct.getTempId()).getStockAreaCode());
        //发货时间
        storeProductResponse.setDeliveryTime(productUtil.getDeliveryTimeByTempId(storeProduct.getTempId(),storeProduct.getIsEurope(),storeProduct.getMerId(),storeProduct.getId()));
        //收货时间
        String receivingTime = productUtil.getReceivingTime(storeProductResponse.getStockArea(), storeProductResponse.getIsEurope(),storeProduct.getMerId(),storeProduct.getId());
        storeProductResponse.setReceivingTime(receivingTime);
        // 设置sku属性
        storeProductResponse.setAttr(attrService.getByProductId(storeProduct.getId()));
        List<StoreProductAttrValue> storeProductAttrValues = storeProductAttrValueService.getListByProductId(storeProduct.getId());
        // 如果不是小程序，而是后台展示，则将拼团锁定库存和剩余可用库存相加作为总库存
        for(StoreProductAttrValue attrValue : storeProductAttrValues){
            if (null == attrValue || null == attrValue.getGroupStock() || attrValue.getGroupStock() <= 0) {
                continue;
            }
            attrValue.setStock(attrValue.getStock() + attrValue.getGroupStock());
        }
        if (CollectionUtils.isEmpty(storeProductAttrValues)) {
            return storeProductResponse;
        }

        if (storeProductResponse.getPrice() == null || storeProductResponse.getOtPrice() == null) {
            calcPriceForAttrValues(storeProductAttrValues, storeProductResponse);
        }
        // 根据attrValue生成前端所需的数据
        List<HashMap<String, Object>> attrValues = new ArrayList<>();
        Map<String, StoreProductAttrValue> valMap = new HashMap<>();
        for(StoreProductAttrValue spav : storeProductAttrValues) {
            valMap.put(spav.getAttrValue(), spav);
        }
        if (storeProduct.getSpecType()) {
            // 后端多属性用于编辑
            StoreProductAttrResult attrResult = storeProductAttrResultService.getByProductId(storeProduct.getId());
            //PC 端生成skuAttrInfo
            List<StoreProductAttrValueRequest> storeProductAttrValueRequests = com.alibaba.fastjson.JSONObject.parseArray(attrResult.getResult(), StoreProductAttrValueRequest.class);
            if (null != storeProductAttrValueRequests) {
                for (int i = 0; i < storeProductAttrValueRequests.size(); i++) {
                    StoreProductAttrValueRequest storeProductAttrValueRequest = storeProductAttrValueRequests.get(i);
                    StoreProductAttrValue attrVal = valMap.get(JSON.toJSONString(storeProductAttrValueRequest.getAttrValue()));
                    if(null == attrVal) {
                        continue;
                    }
                    HashMap<String, Object> attrValue = new HashMap<>();
                    attrValue.put("image", storeProductAttrValueRequest.getImage());
                    attrValue.put("cost", storeProductAttrValueRequest.getCost());
                    attrValue.put("price", storeProductAttrValueRequest.getPrice());
                    attrValue.put("otPrice", storeProductAttrValueRequest.getOtPrice());
                    // 不能显示result里的库存
                    if(null != attrVal.getGroupStock() && attrVal.getGroupStock() > 0) {
                        attrValue.put("stock", attrVal.getStock() + attrVal.getGroupStock());
                    }else {
                        attrValue.put("stock", attrVal.getStock());
                    }
                    attrValue.put("barCode", storeProductAttrValueRequest.getBarCode());
                    attrValue.put("weight", storeProductAttrValueRequest.getWeight());
                    attrValue.put("volume", storeProductAttrValueRequest.getVolume());
                    attrValue.put("suk", attrVal.getSuk());
                    attrValue.put("attrValue", JSON.parse(attrVal.getAttrValue()));
                    attrValue.put("brokerage", storeProductAttrValueRequest.getBrokerage());
                    attrValue.put("brokerage_two", storeProductAttrValueRequest.getBrokerageTwo());
                    Iterator<Map.Entry<String, String>> iterator = storeProductAttrValueRequest.getAttrValue().entrySet().iterator();
                    int j = 0;
                    while (iterator.hasNext()) {
                        Map.Entry<String, String> entry = iterator.next();
                        attrValue.put("value" + j, entry.getValue());
                        j += 1;
                    }
                    attrValues.add(attrValue);
                }
            }
        }

        // H5 端用于生成skuList
        List<StoreProductAttrValueResponse> sPAVResponses = new ArrayList<>();
        for (StoreProductAttrValue storeProductAttrValue : storeProductAttrValues) {
            StoreProductAttrValueResponse atr = new StoreProductAttrValueResponse();
            BeanUtils.copyProperties(storeProductAttrValue, atr);
            sPAVResponses.add(atr);
        }
        storeProductResponse.setAttrValues(attrValues);
        storeProductResponse.setAttrValue(sPAVResponses);

        return storeProductResponse;
    }

    /**
     * 渠道商品列表 - 带分页
     * @param reqParam
     * @param pageParam
     * @return
     */
    @Override
    public PageInfo<ChannelProductVo> selectChannelProductListPage(ChannelProductRequest reqParam, PageParamRequest pageParam) {
        if(!Objects.isNull(reqParam.getPushFlag())){
           return selectChannelProductListByNoPush(reqParam,pageParam);
        }else{
            return selectChannelProductList(reqParam,pageParam);
        }
    }

    /**
     * 渠道商品列表
     * @param reqParam
     * @return
     */
    @Override
    public List<ChannelProductVo> selectChannelProductList(ChannelProductRequest reqParam) {
    	List<ChannelProductVo> storeProducts = storeProductDAO.selectChannelProductList(reqParam);
        // 匹配详情属性(此处应该不需要, 要的话就开启即可 author: daigb)
        // productConvertUtil.convertProduct(storeProducts);
        productConvertUtil.convertProductVoImage(storeProducts);

        return storeProducts;
    }

    /**
     * 产品列表
     * @param request
     * @param pageParamRequest
     * @return
     */
    @Override
    public List<StoreProduct> getList(IndexStoreProductSearchRequest request, PageParamRequest pageParamRequest) {
        LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //查询条件
        queryCondition(request, lambdaQueryWrapper);
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<StoreProduct> storeProducts = storeProductDAO.selectList(lambdaQueryWrapper);
        productConvertUtil.convertProduct(storeProducts);
        return storeProducts;

        // 匹配详情属性(此处应该不需要, 要的话就开启即可 author: daigb)

    }

    /**
     * 商品列表 - 查询条件
     * @param request
     * @param lambdaQueryWrapper
     */
    private void queryCondition(IndexStoreProductSearchRequest request, LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper) {

        //必要条件
        lambdaQueryWrapper.eq(StoreProduct::getIsDel, false)
                // .eq(StoreProduct::getMerId, false)
                .gt(StoreProduct::getStock, 0).eq(StoreProduct::getIsShow, true);

        //搜索关键词
        String keywords = request.getKeywords();
        if (StringUtils.isNotBlank(keywords)) {
            //获取商品id
            Integer productId = getProductIdByKeywords(keywords);

            //获取品牌id
            List<Integer> brandIdList = getOneByBrandName(keywords);

            int index = keywords.indexOf(" ");
            if(index == -1){
                lambdaQueryWrapper.and(wrap -> wrap.likeLeft(StoreProduct::getKeyword, keywords)
                		.or().like(StoreProduct::getBarCode, keywords)
                		.or().likeLeft(StoreProduct::getStoreName, keywords)
                		.or().like(StoreProduct::getCateId, keywords)
                        //.or().like(StoreProduct::getBrandName, keywords)
                        .or().likeRight(StoreProduct::getStoreName, keywords).or().likeRight(StoreProduct::getKeyword, keywords)
                        .or().likeRight(StoreProduct::getBrandName, keywords).or().likeLeft(StoreProduct::getBrandName, keywords)
                        .or().like(null != productId, StoreProduct::getId, productId).or().in(CollectionUtils.isNotEmpty(brandIdList), StoreProduct::getBrandId, brandIdList));
            }else {
                String [] keywordarr = keywords.split("\\s+");
                for (String key : keywordarr){
                    lambdaQueryWrapper.and(wrap -> wrap.likeLeft(StoreProduct::getKeyword, key)
                    		.or().like(StoreProduct::getBarCode, key)
                    		.or().likeLeft(StoreProduct::getStoreName, key)
                    		.or().like(StoreProduct::getCateId, key)
                            //.or().like(StoreProduct::getBrandName, keywords)
                            .or().likeRight(StoreProduct::getStoreName, key).or().likeRight(StoreProduct::getKeyword, key)
                            .or().likeRight(StoreProduct::getBrandName, key).or().likeLeft(StoreProduct::getBrandName, key)
                            .or().like(null != productId, StoreProduct::getId, productId).or().in(CollectionUtils.isNotEmpty(brandIdList), StoreProduct::getBrandId, brandIdList));
                }
            }
        }

        //意大利轮播图-商品列表
        if (BooleanUtil.isTrue(request.getIsEurope())) {
            lambdaQueryWrapper.eq(StoreProduct::getIsEurope, ProductTypeEnum.EUROPE.getCode());
        }

        //发货地
        if (request.getStockArea() != null && StringUtils.isNotBlank(request.getStockArea())) {
            List<Integer> stockAreaList = new ArrayList<>();
            String[] strAreas = request.getStockArea().split(",");
            for (String s : strAreas) {
                stockAreaList.add(Integer.parseInt(s));
            }
            lambdaQueryWrapper.in(StoreProduct::getTempId, stockAreaList);
        }

        //图搜BarCode
        if (null != request.getBarCodeArr() && request.getBarCodeArr().size() > 0) {
            lambdaQueryWrapper.in(StoreProduct::getBarCode, request.getBarCodeArr());
        }

        if(request.getMinPrice() !=null && request.getMaxPrice() == null){
            lambdaQueryWrapper.ge(StoreProduct::getPrice,request.getMinPrice());
        }else if(request.getMinPrice() == null && request.getMaxPrice() != null){
            lambdaQueryWrapper.le(StoreProduct::getPrice,request.getMaxPrice());
        }else if(request.getMinPrice() !=null && request.getMaxPrice()!= null){
            lambdaQueryWrapper.between(StoreProduct::getPrice,request.getMinPrice(),request.getMaxPrice());
        }

        //新品
        if (request.getIsNew() != null) {
            lambdaQueryWrapper.eq(StoreProduct::getIsNew, request.getIsNew());
        }

        //品牌
        if (request.getBrandId() != null) {
            lambdaQueryWrapper.eq(StoreProduct::getBrandId, request.getBrandId());
        }
        if (request.getBrandIds() != null && StringUtils.isNotBlank(request.getBrandIds())) {
            String[] brds = request.getBrandIds().split(",");
            lambdaQueryWrapper.in(StoreProduct::getBrandId, Arrays.asList(brds));
        }

        //类目
        if (null != request.getCateId() && request.getCateId().size() > 0) {
            lambdaQueryWrapper.in(StoreProduct::getCateId, request.getCateId());
            //            lambdaQueryWrapper.apply(CrmebUtil.getFindInSetSql("cate_id", (ArrayList<Integer>) request.getCateId()));
        }

        //精选/小编推荐
        if (request.getIsBest() != null) {
            lambdaQueryWrapper.eq(StoreProduct::getIsBest, request.getIsBest());
            lambdaQueryWrapper.orderByDesc(StoreProduct::getBestTime);
        }

        if(!Objects.isNull(request.getMerId())){
            lambdaQueryWrapper.eq(StoreProduct::getMerId, request.getMerId());
            lambdaQueryWrapper.or(i -> i.or().eq(StoreProduct::getMerId, request.getMerId()).eq(StoreProduct::getIsEurope,ProductTypeEnum.INSIDE.getCode()));
        }

        if (StringUtils.isNotBlank(keywords)) {

            lambdaQueryWrapper.orderByDesc(StoreProduct::getBrandId).orderByDesc(StoreProduct::getKeyword).orderByDesc(StoreProduct::getStoreName).orderByDesc(StoreProduct::getCateId);
        }

        //价格排序
        if (!StringUtils.isBlank(request.getPriceOrder())) {
            if (request.getPriceOrder().equals(Constants.SORT_DESC)) {
                lambdaQueryWrapper.orderByDesc(StoreProduct::getPrice);
            } else {
                lambdaQueryWrapper.orderByAsc(StoreProduct::getPrice);
            }
        }

        //销量排序
        if (!StringUtils.isBlank(request.getSalesOrder())) {
            if (request.getSalesOrder().equals(Constants.SORT_DESC)) {
                lambdaQueryWrapper.orderByDesc(StoreProduct::getSales);
            } else {
                lambdaQueryWrapper.orderByAsc(StoreProduct::getSales);
            }
        }

    }

    /**
     * 商品列表 - 获取商品id
     * @param keywords
     * @return
     */
    private Integer getProductIdByKeywords(String keywords) {
        Integer productId = null;
        if (CrmebUtil.isString2Num(keywords) && 9 > keywords.length()) {
            productId = Integer.valueOf(keywords);
        }
        return productId;
    }

    /**
     * 商品列表 - 根据品牌名称, 获取品牌id
     * @param brandName
     * @return
     */
    private List<Integer> getOneByBrandName(String brandName) {

        if (brandName.matches(".*?[a-zA-Z]+.*?")) {
            //全部小写
            brandName = brandName.toLowerCase();
        }

        return storeBrandService.brandIdlist(brandName);
    }

    /**
     * 首字母转大写
     * @param s
     * @return
     */
    public static String toUpperCaseFirstOne(String s) {
        //全部转换小写
        String lowerCase = s.toLowerCase();
        if (Character.isUpperCase(lowerCase.charAt(0))) {
            return s;
        } else {
            return (new StringBuilder()).append(Character.toUpperCase(lowerCase.charAt(0))).append(lowerCase.substring(1)).toString();
        }
    }

    /**
     * 根据商品tabs获取对应类型的产品数量
     * @return
     */
    @Override
    @RateLimiter(qps = 10, timeout = 1, timeUnit = TimeUnit.SECONDS)
    public List<StoreProductTabsHeader> getTabsHeader(int type) {
        List<StoreProductTabsHeader> headers = new ArrayList<>();
        StoreProductTabsHeader header1 = new StoreProductTabsHeader(0, "出售中商品", 1);
        StoreProductTabsHeader header2 = new StoreProductTabsHeader(0, "仓库中商品", 2);
        StoreProductTabsHeader header3 = new StoreProductTabsHeader(0, "已经售馨商品", 3);
        StoreProductTabsHeader header4 = new StoreProductTabsHeader(0, "警戒库存", 4);
        StoreProductTabsHeader header5 = new StoreProductTabsHeader(0, "商品回收站", 5);
        StoreProductTabsHeader header6 = new StoreProductTabsHeader(0, "待审核", 6);
        headers.add(header1);
        headers.add(header2);
        headers.add(header3);
        headers.add(header4);
        headers.add(header5);
        headers.add(header6);

        List<Integer> merIds = systemAdminService.getAdminMerIds();
        for (StoreProductTabsHeader h : headers) {
            LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            // 自建列表
            if (1 == type) {
                lambdaQueryWrapper.eq(StoreProduct :: getIsEurope, ProductTypeEnum.INSIDE.getCode()).isNull(StoreProduct::getConvertIsEurope);
                lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(merIds), StoreProduct :: getMerId, merIds);
            }else if(2 == type) {
                lambdaQueryWrapper.and(e->e.ne(StoreProduct :: getIsEurope, ProductTypeEnum.INSIDE.getCode())
                        .or(i->i.eq(StoreProduct::getIsEurope,1).isNotNull(StoreProduct::getConvertIsEurope)));
            }
//            // 自建列表
//            if(1 == type) {
//                lambdaQueryWrapper.eq(StoreProduct :: getIsEurope, ProductTypeEnum.INSIDE);
//                lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(merIds), StoreProduct :: getMerId, merIds);
//            // 供应商列表
//            } else if(2 == type) {
//                List<Integer> productTypes = Arrays.asList(ProductTypeEnum.INSIDE.getCode());
//                lambdaQueryWrapper.notIn(StoreProduct :: getIsEurope, productTypes);
//            }
            switch (h.getType()) {
            case 1:
                //出售中（已上架）
                lambdaQueryWrapper.eq(StoreProduct::getIsShow, true);
                lambdaQueryWrapper.eq(StoreProduct::getIsDel, false);
                // 库存为0的商品不显示在出售中列表
                lambdaQueryWrapper.gt(StoreProduct::getStock, 0);
                break;
            case 2:
                //仓库中（未上架）
                lambdaQueryWrapper.eq(StoreProduct::getIsShow, false);
                lambdaQueryWrapper.eq(StoreProduct::getIsDel, false);
                break;
            case 3:
                //已售罄
                lambdaQueryWrapper.le(StoreProduct::getStock, 0);
                lambdaQueryWrapper.eq(StoreProduct::getIsDel, false);
                break;
            case 4:
                //警戒库存
                Integer stock = Integer.parseInt(systemConfigService.getValueByKey("store_stock"));
                lambdaQueryWrapper.le(StoreProduct::getStock, stock);
                lambdaQueryWrapper.gt(StoreProduct::getStock, 0);
                lambdaQueryWrapper.eq(StoreProduct::getIsDel, false);
                break;
            case 5:
                //回收站
                lambdaQueryWrapper.eq(StoreProduct::getIsDel, true);
                break;
            case 6:
                //待审核
                lambdaQueryWrapper.eq(StoreProduct::getSelfPushStatus, 1);
                break;
            default:
                break;
            }
//            lambdaQueryWrapper.orderByAsc(StoreProduct::getId);
//            Page<Object> page = PageHelper.startPage(1, 1);
//            storeProductDAO.selectList(lambdaQueryWrapper);
            Integer count =  storeProductDAO.selectCount(lambdaQueryWrapper);
            h.setCount(count);
        }

        return headers;
    }

    /**
     * 库存变动写入redis队列
     * @param request StoreProductStockRequest 参数对象
     * @author Mr.Zhang
     * @since 2020-05-06
     * @return int
     */
    @Override
    public boolean stockAddRedis(StoreProductStockRequest request) {
        //        redisUtil.lPush(Constants.PRODUCT_STOCK_UPDATE, JSON.toJSONString(request));
        doProductStock(request);
        return true;
    }

    @Override
    public void consumeProductStock() {
        String redisKey = Constants.PRODUCT_STOCK_UPDATE;
        Long size = redisUtil.getListSize(redisKey);
        logger.info("StoreProductServiceImpl.doProductStock | size:" + size);
        if (size < 1) {
            return;
        }
        for (int i = 0; i < size; i++) {
            //如果10秒钟拿不到一个数据，那么退出循环
            Object data = redisUtil.getRightPop(redisKey, 10L);
            if (null == data) {
                continue;
            }
            try {
                StoreProductStockRequest storeProductStockRequest = com.alibaba.fastjson.JSONObject.toJavaObject(com.alibaba.fastjson.JSONObject.parseObject(data.toString()), StoreProductStockRequest.class);
                boolean result = doProductStock(storeProductStockRequest);
                if (!result) {
                    redisUtil.lPush(redisKey, data);
                }
            } catch (Exception e) {
                redisUtil.lPush(redisKey, data);
            }
        }
    }

    /**
     * 扣减库存添加销量
     * @param productId 产品id
     * @param num 商品数量
     * @param type 是否限购 0=不限购
     * @return 扣减结果
     */
    @Override
    public boolean decProductStock(Integer productId, Integer num, String attrValueId, Integer type, Integer activityGroupId) {
        // 因为attrvalue表中unique使用Id代替，更新前先查询此表是否存在
        // 不存在=但属性 存在则是多属性
        StoreProduct storeProduct = getById(productId);
        if (storeProduct == null || storeProduct.getStock() <= 0 || !storeProduct.getIsShow()) {
            throw new CrmebException("订单生成失败,商品已下架!");
        }

        boolean result = storeProductAttrValueService.decProductAttrStock(productId, attrValueId, num, type, activityGroupId);
        if (!result) {
            throw new CrmebException("商品已售完!");
        }

        LambdaUpdateWrapper<StoreProduct> lqwuper = new LambdaUpdateWrapper<>();
        lqwuper.eq(StoreProduct::getId, productId);
        lqwuper.ge(StoreProduct::getStock, num);
        lqwuper.set(StoreProduct::getStock, storeProduct.getStock() - num);
        lqwuper.set(StoreProduct::getSales, storeProduct.getSales() + num);
        result = update(lqwuper);
        if (result) { //判断库存警戒值
            Integer alterNumI = 0;
            String alterNum = systemConfigService.getValueByKey("store_stock");
            if (StringUtils.isNotBlank(alterNum))
                alterNumI = Integer.parseInt(alterNum);
//            StoreProductAttrValue productsInAttrValue = storeProductAttrValueService.getById(attrValueId);
            StoreProductAttrValue productsInAttrValue = storeProductAttrValueService.getOne(Wrappers.lambdaQuery(StoreProductAttrValue.class)
                    .eq(StoreProductAttrValue::getSourceSkuId,attrValueId)
                    .eq(StoreProductAttrValue::getProductId,productId)
                    .last("LIMIT 1"));
            if (alterNumI >= productsInAttrValue.getStock()) {
                // todo socket 发送库存警告
            }
            //修改最低价格
            log.info("---------------修改商品最低价格,库存:{}-------------",productsInAttrValue.getStock());
            if(productsInAttrValue.getStock() <= 0){
                ThreadPoolUtils.getThread().submit(() -> updateProductMinPrice(storeProduct));
            }
        }
        return result;
    }

    @Override
    public boolean decPickingProductStock(Integer productId, Integer num, String attrValueId, Integer type) {
        // 因为attrvalue表中unique使用Id代替，更新前先查询此表是否存在
        // 不存在=但属性 存在则是多属性
        StoreProduct storeProduct = getById(productId);
        if (storeProduct == null || storeProduct.getStock() <= 0 || !storeProduct.getIsShow()) {
            throw new CrmebException("订单生成失败,商品已下架!");
        }

        List<StoreProductAttrValue> existAttrValues = storeProductAttrValueService.getListByProductIdAndSkuId(productId, attrValueId+"");
//        List<StoreProductAttrValue> existAttrValues = storeProductAttrValueService.getListByProductIdAndSkuId(productId, attrValueId);
        if(existAttrValues.size() == 0){
            throw new CrmebException("商品已售完");
        }

        StoreProductAttrValue attrValue = existAttrValues.get(0);
        // 为什么一件的时候不能卖
        if(num > attrValue.getStock()){
            throw new CrmebException("库存不足");
        }
        return true;
    }

    @Override
    public void updateVideo(StoreProductRequest storeProductRequest) {
        StoreProduct product = storeProductDAO.selectById(storeProductRequest.getId());
        if(null == product)throw new CrmebException("商品不存在");
        // 处理富文本
        StoreProductRequest  request = new StoreProductRequest();
        StoreProductDescription dbDescription = storeProductDescriptionService.getOne(Wrappers.<StoreProductDescription>lambdaQuery()
                .eq(StoreProductDescription :: getProductId, storeProductRequest.getId())
                .last("LIMIT 1")
        );
        StoreProductDescription storeProductDescription = StoreProductDescription.getDescriptionByRequest(storeProductRequest);
        if(null != dbDescription){
            storeProductDescription = dbDescription;
        }
        storeProductDescription.setVideo(storeProductRequest.getVideoLink());
        storeProductDescription.setId(ObjectUtil.isNotNull(dbDescription) ? dbDescription.getId() : null);
        storeProductDescription.setProductId(storeProductRequest.getId());
        storeProductDescriptionService.saveOrUpdate(storeProductDescription);
    }

    @Override
    public void updateKeyword(StoreProduct storeProduct) {
        storeProductDAO.updateKeyword(storeProduct.getId(), storeProduct.getKeyword());
    }

    @Override
    public void updateProductMinPrice(StoreProduct storeProduct) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("---------------修改商品最低价格:{}-------------",storeProduct.getId());
        List<StoreProductAttrValue> productAttrValueList = storeProductAttrValueService.list(Wrappers.lambdaQuery(StoreProductAttrValue.class).eq(StoreProductAttrValue::getProductId, storeProduct.getId()).gt(StoreProductAttrValue::getStock, 0));
        if(CollectionUtils.isNotEmpty(productAttrValueList)){
            //售价最低
            List<StoreProductAttrValue> sortList = productAttrValueList.stream().sorted(Comparator.comparing(StoreProductAttrValue::getPrice)).collect(Collectors.toList());
            StoreProductAttrValue productAttrValue = sortList.get(0);
            if(productAttrValue.getPrice().compareTo(storeProduct.getPrice()) != 0){
                this.update(Wrappers.lambdaUpdate(StoreProduct.class).set(StoreProduct::getPrice, productAttrValue.getPrice())
                        .set(StoreProduct::getCost,productAttrValue.getCost())
                        .set(StoreProduct::getSourceCost,productAttrValue.getSourceCost())
                        .set(StoreProduct::getOtPrice,productAttrValue.getOtPrice())
                        .eq(StoreProduct::getId, storeProduct.getId()));
            }
//            Optional<BigDecimal> minPrice = productAttrValueList.stream().map(StoreProductAttrValue::getPrice).min(BigDecimal::compareTo);
//            minPrice.ifPresent(bigDecimal -> {
//                if(bigDecimal.compareTo(storeProduct.getPrice()) != 0){
//                    this.update(Wrappers.lambdaUpdate(StoreProduct.class).set(StoreProduct::getPrice, bigDecimal).eq(StoreProduct::getId, storeProduct.getId()));
//                    log.info("---------------修改商品最低价格,主表id:{},价格:{}-------------",storeProduct.getId(),minPrice);
//                }
//            });
//            //原价最低
//            Optional<BigDecimal> minOtPrice = productAttrValueList.stream().map(StoreProductAttrValue::getOtPrice).min(BigDecimal::compareTo);
//            minOtPrice.ifPresent(bigDecimal -> {
//                if(bigDecimal.compareTo(storeProduct.getOtPrice()) != 0){
//                    this.update(Wrappers.lambdaUpdate(StoreProduct.class).set(StoreProduct::getOtPrice, bigDecimal).eq(StoreProduct::getId, storeProduct.getId()));
//                    log.info("---------------修改商品最低价格,主表id:{},原价:{}-------------",storeProduct.getId(),minPrice);
//                }
//            });
            if(storeProduct.getIsEurope() == 1 && Objects.isNull(storeProduct.getConvertIsEurope())){
                return;
            }
            List<ChannelMerchant> channelMerchantList = channelMerchantService.list(Wrappers.lambdaQuery(ChannelMerchant.class)
            		.eq(ChannelMerchant::getIsDel, 0)
            		.in(ChannelMerchant::getChannelType, Arrays.asList(1, 2, 8))
            		.select(ChannelMerchant::getId)
            		);
            if(CollectionUtils.isNotEmpty(channelMerchantList)){
                List<Integer> merIdList = channelMerchantList.stream().map(ChannelMerchant::getId).collect(Collectors.toList());
                merIdList.parallelStream().forEach(e -> {
                    MybatisPlusConfig.tableNameMp.set(TableNameUtil.getProductMerName(e));
                    try {
                        StoreProductMer storeProductMer = storeProductMerService.getOne(Wrappers.lambdaQuery(StoreProductMer.class)
                        		.eq(StoreProductMer::getProductId, storeProduct.getId())
                        		.eq(StoreProductMer::getPriceType,1)
                        		);
                        if(storeProductMer != null){
                            List<String> sourceSkuIdList = productAttrValueList.stream().map(StoreProductAttrValue::getSourceSkuId).collect(Collectors.toList());
                            MybatisPlusConfig.productValueNameMp.set(TableNameUtil.getProductValueMerName(e));
                            List<StoreProductValueMer> storeProductValueMerList = storeProductValueMerService.list(Wrappers.lambdaQuery(StoreProductValueMer.class)
                            		.eq(StoreProductValueMer::getProductId, storeProduct.getId())
                            		.in(StoreProductValueMer::getSourceSkuId, sourceSkuIdList)
                            		);
                            Optional<BigDecimal> min = storeProductValueMerList.stream().map(StoreProductValueMer::getPrice).min(BigDecimal::compareTo);
                            if(min.isPresent()){
                                if(min.get().compareTo(storeProductMer.getPrice()) != 0){
                                    storeProductMer.setPrice(min.get());
                                    MybatisPlusConfig.tableNameMp.set(TableNameUtil.getProductMerName(e));
                                    storeProductMerService.updateById(storeProductMer);
                                    log.info("---------------修改商品最低价格成功,商品id:{},商户id:{},价格:{}-------------",storeProduct.getId(),e,min.get());
                                }
                            }
                        }
                    }catch (Exception e1){
                        log.error("---------------修改商品最低价格失败,商品id:{},商户id:{},{}-------------",storeProduct.getId(),e,e1.getMessage());
                    }
                });
            }
        }
    }

    @Override
    public Boolean subProductStock(Integer productId, Integer stock) {
        int updateCount = storeProductDAO.subProductStock(productId, stock);
        return 0 > updateCount ? true : false;
    }

    /**
     * 根据商品id取出二级分类
     * @param productIdStr String 商品分类
     * @return List<Integer>
     */
    @Override
    public List<Integer> getSecondaryCategoryByProductId(String productIdStr) {
        List<Integer> idList = new ArrayList<>();

        if (StringUtils.isBlank(productIdStr)) {
            return idList;
        }
        List<Integer> productIdList = CrmebUtil.stringToArray(productIdStr);
        LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(StoreProduct::getId, productIdList);
        List<StoreProduct> productList = storeProductDAO.selectList(lambdaQueryWrapper);
        if (productIdList.size() < 1) {
            return idList;
        }

        //把所有的分类id写入集合
        for (StoreProduct storeProduct : productList) {
            List<Integer> categoryIdList = Arrays.asList(storeProduct.getCateId());
            idList.addAll(categoryIdList);
        }

        //去重
        List<Integer> cateIdList = idList.stream().distinct().collect(Collectors.toList());
        if (cateIdList.size() < 1) {
            return idList;
        }
        //取出所有的二级分类
        List<CategoryMatch> categoryMatchList =  categoryMatchService.getByIds(cateIdList);
//        List<Category> categoryList = categoryService.getByIds(cateIdList);
        if (categoryMatchList.size() < 1) {
            return idList;
        }
        for (CategoryMatch category : categoryMatchList) {
            List<Integer> parentIdList = CrmebUtil.stringToArrayByRegex(category.getPath(), "/");
            if (parentIdList.size() > 2) {
                Integer secondaryCategoryId = parentIdList.get(2);
                if (secondaryCategoryId > 0) {
                    idList.add(secondaryCategoryId);
                }
            }

        }
        return idList;
    }

    /**
     * 根据其他平台url导入产品信息
     * @param url 待导入平台url
     * @param tag 1=淘宝，2=京东，3=苏宁，4=拼多多， 5=天猫
     * @return
     */
    @Override
    public StoreProductRequest importProductFromUrl(String url, int tag) {
        StoreProductRequest productRequest = null;
        try {
            switch (tag) {
            case 1:
                productRequest = getTaobaoProductInfo(url, tag);
                break;
            case 2:
                productRequest = getJDProductInfo(url, tag);
                break;
            case 3:
                productRequest = getSuningProductInfo(url, tag);
                break;
            case 4:
                productRequest = getPddProductInfo(url, tag);
                break;
            case 5:
                productRequest = getTmallProductInfo(url, tag);
                break;
            }
        } catch (Exception e) {
            throw new CrmebException("确认URL和平台是否正确，以及平台费用是否足额" + e.getMessage());
        }
        return productRequest;
    }

    private String baseUrl;

    String rightUrl;

    /**
     * 设置优惠券信息
     * @param storeProductRequest 商品request信息
     * @param storeProduct 商品信息
     */
    private void shipProductCoupons(StoreProductRequest storeProductRequest, StoreProduct storeProduct) {
        if (null != storeProductRequest.getCouponIds() && storeProductRequest.getCouponIds().size() > 0) {
            storeProductCouponService.deleteByProductId(storeProduct.getId());
            List<StoreProductCoupon> spcs = new ArrayList<>();
            for (Integer couponId : storeProductRequest.getCouponIds()) {
//                StoreProductCoupon spc = new StoreProductCoupon(storeProduct.getId(), couponId, DateUtil.getNowTime());
//                spcs.add(spc);
            }
            storeProductCouponService.saveCoupons(spcs);
        }
    }

    /**
     * 解析淘宝产品数据
     * @param url
     * @param tag
     * @throws IOException
     * @throws JSONException
     */
    public StoreProductRequest getTaobaoProductInfo(String url, int tag) throws JSONException, IOException {
        setConfig(url, tag);
        JSONObject tbJsonData = getRequestFromUrl(baseUrl + rightUrl);
        //        JSONObject tbJsonData = new JSONObject(JSONExample.tbJson); // just Test
        JSONObject data = tbJsonData.getJSONObject("data");
        if (null == data)
            throw new CrmebException("复制商品失败--返回数据格式错误--未找到data");
        JSONObject item = data.getJSONObject("item");
        if (null == item)
            throw new CrmebException("复制商品失败--返回数据格式错误--未找到item");

        StoreProductRequest productRequest = new StoreProductRequest();
        StoreProduct product = new StoreProduct();
        product.setStoreName(item.getString("title"));
        product.setStoreInfo(item.getString("title"));
        product.setSliderImage(item.getString("images"));
        product.setImage(item.getString("images").split(",")[0].replace("[", "").replace("\"", ""));
        product.setKeyword(item.getString("title"));
        BeanUtils.copyProperties(product, productRequest);
        productRequest.setContent(item.getString("desc"));

        JSONArray props = item.getJSONArray("props");
        if (null == props)
            throw new CrmebException("复制商品失败--返回数据格式错误--未找到props");
        if (props.length() > 0) {
            List<StoreProductAttr> spaAttes = new ArrayList<>();
            for (int i = 0; i < props.length(); i++) {
                JSONObject pItem = props.getJSONObject(i);
                StoreProductAttr spattr = new StoreProductAttr();
                spattr.setAttrName(pItem.getString("name"));
                JSONArray values = pItem.getJSONArray("values");
                List<String> attrValues = new ArrayList<>();
                for (int j = 0; j < values.length(); j++) {
                    JSONObject value = values.getJSONObject(j);
                    attrValues.add(value.getString("name"));
                }
                spattr.setAttrValues(attrValues.toString());
                spaAttes.add(spattr);
            }
            productRequest.setAttr(spaAttes);
        }
        return productRequest;
    }

    /**
     * 解析京东产品数据
     * @param url
     * @param tag
     * @return
     * @throws JSONException
     */
    public StoreProductRequest getJDProductInfo(String url, int tag) throws JSONException, IOException {
        setConfig(url, tag);
        JSONObject tbJsonData = getRequestFromUrl(baseUrl + rightUrl);
        //        JSONObject tbJsonData = new JSONObject(JSONExample.jdJson); // just Test
        JSONObject data = tbJsonData.getJSONObject("data");
        if (null == data)
            throw new CrmebException("复制商品失败--返回数据格式错误--未找到data");
        JSONObject item = data.getJSONObject("item");
        if (null == item)
            throw new CrmebException("复制商品失败--返回数据格式错误--未找到item");

        StoreProductRequest productRequest = new StoreProductRequest();
        StoreProduct product = new StoreProduct();
        product.setStoreName(item.getString("name"));
        product.setStoreInfo(item.getString("name"));
        product.setSliderImage(item.getString("images"));
        product.setImage(item.getString("images").split(",")[0].replace("[", "").replace("\"", ""));
        product.setPrice(BigDecimal.valueOf(item.getDouble("price")));
        BeanUtils.copyProperties(product, productRequest);
        productRequest.setContent(item.getString("desc"));

        JSONObject props = item.getJSONObject("skuProps");
        if (null == props)
            throw new CrmebException("复制商品失败--返回数据格式错误--未找到props");
        List<StoreProductAttr> spaAttes = new ArrayList<>();
        JSONObject saleJson = item.getJSONObject("saleProp");
        int attrValueIsNullCount = 0;
        Iterator<String> saleProps = saleJson.keys();
        while (saleProps.hasNext()) {
            StoreProductAttr spattr = new StoreProductAttr();
            String stepkey = saleProps.next();
            String stepValue = props.getString(stepkey);
            String stepValueValidLength = stepValue.replace("[", "").replace("]", "").replace("\"", "");
            if (stepValueValidLength.length() > 0) {
                com.alibaba.fastjson.JSONArray stepValues = JSON.parseArray(stepValue);
                int c = stepValues.get(0).toString().length();
                attrValueIsNullCount += c == 0 ? 1 : 0;
                spattr.setAttrName(saleJson.getString(stepkey));
                spattr.setAttrValues(props.getString(stepkey));
                spaAttes.add(spattr);
                productRequest.setAttr(spaAttes);
            } else {
                attrValueIsNullCount += 1;
            }
        }
        // 判断是否单属性
        productRequest.setSpecType(spaAttes.size() != attrValueIsNullCount);
        return productRequest;
    }

    /**
     * 解析天猫产品数据
     * @param url
     * @param tag
     * @return
     * @throws JSONException
     */
    public StoreProductRequest getTmallProductInfo(String url, int tag) throws JSONException, IOException {
        setConfig(url, tag);
        JSONObject tbJsonData = getRequestFromUrl(baseUrl + rightUrl);
        //        JSONObject tbJsonData = new JSONObject(JSONExample.tmallJson); // just Test
        JSONObject data = tbJsonData.getJSONObject("data");
        if (null == data)
            throw new CrmebException("复制商品失败--返回数据格式错误--未找到data");
        JSONObject item = data.getJSONObject("item");
        if (null == item)
            throw new CrmebException("复制商品失败--返回数据格式错误--未找到item");

        StoreProductRequest productRequest = new StoreProductRequest();
        StoreProduct product = new StoreProduct();
        product.setStoreName(item.getString("title"));
        product.setStoreInfo(item.getString("subTitle"));
        product.setSliderImage(item.getString("images"));
        product.setImage(item.getString("images").split(",")[0].replace("[", "").replace("\"", ""));
        product.setKeyword(item.getString("title"));
        BeanUtils.copyProperties(product, productRequest);
        productRequest.setContent(item.getString("desc"));

        JSONArray props = item.getJSONArray("props");
        if (null == props)
            throw new CrmebException("复制商品失败--返回数据格式错误--未找到props");
        if (props.length() > 0) {
            List<StoreProductAttr> spaAttes = new ArrayList<>();
            for (int i = 0; i < props.length(); i++) {
                JSONObject pItem = props.getJSONObject(i);
                StoreProductAttr spattr = new StoreProductAttr();
                spattr.setAttrName(pItem.getString("name"));
                JSONArray values = pItem.getJSONArray("values");
                List<String> attrValues = new ArrayList<>();
                for (int j = 0; j < values.length(); j++) {
                    JSONObject value = values.getJSONObject(j);
                    attrValues.add(value.getString("name"));
                }
                spattr.setAttrValues(attrValues.toString());
                spaAttes.add(spattr);
            }
            productRequest.setAttr(spaAttes);
        }
        return productRequest;
    }

    /**
     * 解析拼多多产品数据
     * @param url
     * @param tag
     * @return
     * @throws JSONException
     */
    public StoreProductRequest getPddProductInfo(String url, int tag) throws JSONException, IOException {
        setConfig(url, tag);
        JSONObject tbJsonData = getRequestFromUrl(baseUrl + rightUrl);
        //        JSONObject tbJsonData = new JSONObject(JSONExample.pddJson); // just Test
        JSONObject data = tbJsonData.getJSONObject("data");
        if (null == data)
            throw new CrmebException("复制商品失败--返回数据格式错误--未找到data");
        JSONObject item = data.getJSONObject("item");
        if (null == item)
            throw new CrmebException("复制商品失败--返回数据格式错误--未找到item");

        StoreProductRequest productRequest = new StoreProductRequest();
        StoreProduct product = new StoreProduct();
        product.setStoreName(item.getString("goodsName"));
        product.setStoreInfo(item.getString("goodsDesc"));
        product.setSliderImage(item.getString("thumbUrl"));
        product.setImage(item.getString("banner"));
//        product.setVideoLink(item.getJSONArray("video").getJSONObject(0).getString("videoUrl"));
        product.setPrice(BigDecimal.valueOf(item.getDouble("maxNormalPrice")));
        product.setOtPrice(BigDecimal.valueOf(item.getDouble("marketPrice")));
        BeanUtils.copyProperties(product, productRequest);

        JSONArray props = item.getJSONArray("skus");
        if (null == props)
            throw new CrmebException("复制商品失败--返回数据格式错误--未找到props");
        if (props.length() > 0) {
            List<StoreProductAttr> spaAttes = new ArrayList<>();
            HashMap<String, List<String>> tempAttr = new HashMap<>();
            for (int i = 0; i < props.length(); i++) {
                JSONObject pItem = props.getJSONObject(i);
                JSONArray specArray = pItem.getJSONArray("specs");
                for (int j = 0; j < specArray.length(); j++) {
                    JSONObject specItem = specArray.getJSONObject(j);
                    String keyTemp = specItem.getString("spec_key");
                    String valueTemp = specItem.getString("spec_value");
                    if (tempAttr.containsKey(keyTemp)) {
                        if (!tempAttr.get(keyTemp).contains(valueTemp)) {
                            tempAttr.get(keyTemp).add(valueTemp);
                        }
                    } else {
                        List<String> tempList = new ArrayList<>();
                        tempList.add(valueTemp);
                        tempAttr.put(keyTemp, tempList);
                    }
                }

            }
            Iterator iterator = tempAttr.keySet().iterator();
            while (iterator.hasNext()) {
                String key = (String) iterator.next();
                StoreProductAttr spattr = new StoreProductAttr();
                spattr.setAttrName(key);
                spattr.setAttrValues(tempAttr.get(key).toString());
                spaAttes.add(spattr);
            }
            productRequest.setAttr(spaAttes);
        }
        return productRequest;
    }

    /** TODO 苏宁返回的数据不一致，暂放
     * 解析苏宁产品数据
     * @param url
     * @param tag
     * @return
     * @throws JSONException
     */
    public StoreProductRequest getSuningProductInfo(String url, int tag) throws JSONException, IOException {
        setConfig(url, tag);
        JSONObject tbJsonData = getRequestFromUrl(baseUrl + rightUrl);
        System.out.println("tbJsonData:" + tbJsonData);
        //        JSONObject tbJsonData = new JSONObject(JSONExample.snJson); // just Test
        JSONObject data = tbJsonData.getJSONObject("data");
        if (null == data)
            throw new CrmebException("复制商品失败--返回数据格式错误--未找到data");

        StoreProductRequest productRequest = new StoreProductRequest();
        StoreProduct product = new StoreProduct();
        product.setStoreName(data.getString("title"));
        product.setStoreInfo(data.getString("title"));
        product.setSliderImage(data.getString("images"));
        product.setImage(data.getString("images").split(",")[0].replace("[", "").replace("\"", ""));
        Long priceS = data.getLong("price");
        product.setPrice(BigDecimal.valueOf(priceS));
        BeanUtils.copyProperties(product, productRequest);
        productRequest.setContent(data.getString("desc"));
        if (null == data.optJSONArray("passSubList")) {
            return productRequest;
        }
        JSONArray props = data.getJSONArray("passSubList");
        if (null == props) {
            return productRequest;
        }
        if (props.length() > 0) {
            List<StoreProductAttr> spaAttes = new ArrayList<>();
            for (int i = 0; i < props.length(); i++) {
                JSONObject pItem = props.getJSONObject(i);
                Iterator it = pItem.keys();
                while (it.hasNext()) {
                    String key = (String) it.next();
                    JSONArray skuItems = pItem.getJSONArray(key);
                    List<String> attrValues = new ArrayList<>();
                    StoreProductAttr spattr = new StoreProductAttr();
                    for (int j = 0; j < skuItems.length(); j++) {
                        JSONObject skuItem = skuItems.getJSONObject(j);
                        if (null != skuItem.optString("characterValueDisplayName"))
                            attrValues.add(skuItem.getString("characterValueDisplayName"));
                    }
                    spattr.setAttrName(key);
                    spattr.setAttrValues(attrValues.toString());
                    spaAttes.add(spattr);
                }
                productRequest.setAttr(spaAttes);
            }
        }
        return productRequest;
    }

    /**
     * 设置配置数据
     * @param tag
     */
    private void setConfig(String url, int tag) {
        String rightEndUrl = "&itemid=";
        switch (tag) { // 导入平台1=淘宝，2=京东，3=苏宁，4=拼多多， 5=天猫
        case 1:
            baseUrl = systemConfigService.getValueByKey("inportProductTB");
            rightEndUrl += UrlUtil.getParamsByKey(url, "id");
            break;
        case 2:
            baseUrl = systemConfigService.getValueByKey("inportProductJD");
            rightEndUrl += url.substring(url.lastIndexOf("/") + 1).replace(".html", "");
            break;
        case 3:
            baseUrl = systemConfigService.getValueByKey("inportProductSN");
            int start = url.indexOf(".com/") + 5;
            int end = url.indexOf(".html");
            String sp = url.substring(start, end);
            String[] shopProduct = sp.split("/");
            rightEndUrl += shopProduct[1] + "&shopid=" + shopProduct[0];
            break;
        case 4:
            rightEndUrl += UrlUtil.getParamsByKey(url, "goods_id");
            baseUrl = systemConfigService.getValueByKey("inportProductPDD");
            break;
        case 5:
            rightEndUrl += UrlUtil.getParamsByKey(url, "id");
            baseUrl = systemConfigService.getValueByKey("inportProductTM");
            break;
        }
        String token = systemConfigService.getValueByKey("importProductToken");
        if (StringUtils.isBlank(token)) {
            throw new CrmebException("请配置复制产品平台的Token -- www.99api.com");
        }
        if (StringUtils.isBlank(baseUrl)) {
            throw new CrmebException("请配置复制产品平台的Url-- www.99api.com");
        }
        rightUrl = "?apikey=" + systemConfigService.getValueByKey("importProductToken") + rightEndUrl;

    }

    /**
     * 99api产品复制工具方法
     * @param rd
     * @return
     * @throws IOException
     */
    private static String readAll(Reader rd) throws IOException {
        StringBuilder sb = new StringBuilder();
        int cp;
        while ((cp = rd.read()) != -1) {
            sb.append((char) cp);
        }
        return sb.toString();
    }

    /**
     * 根据url访问99api后返回对应的平台的产品json数据 带有body参数，暂时无用
     * @param url
     * @param body
     * @return
     * @throws IOException
     * @throws JSONException
     */
    public JSONObject postRequestFromUrl(String url, String body) throws IOException, JSONException {
        URL realUrl = new URL(url);
        URLConnection conn = realUrl.openConnection();
        conn.setDoOutput(true);
        conn.setDoInput(true);
        PrintWriter out = new PrintWriter(conn.getOutputStream());
        out.print(body);
        out.flush();
        InputStream instream = conn.getInputStream();
        try {
            BufferedReader rd = new BufferedReader(new InputStreamReader(instream, StandardCharsets.UTF_8));
            String jsonText = readAll(rd);
            JSONObject json = new JSONObject(jsonText);
            return json;
        } finally {
            instream.close();
        }
    }

    /**
     * 根据url访问99api后返回对应的平台的产品json数据
     * @param url
     * @return
     * @throws IOException
     * @throws JSONException
     */
    public static JSONObject getRequestFromUrl(String url) throws IOException, JSONException {
        URL realUrl = new URL(url);
        URLConnection conn = realUrl.openConnection();
        InputStream instream = conn.getInputStream();
        try {
            BufferedReader rd = new BufferedReader(new InputStreamReader(instream, StandardCharsets.UTF_8));
            String jsonText = readAll(rd);
            JSONObject json = new JSONObject(jsonText);
            return json;
        } finally {
            instream.close();
        }
    }

    /**
     * 计算产品属性之中最大和最小的价格，新增和编辑使用
     * @param storeProductRequest 分析的参数
     * @param storeProduct 当前操作的产品
     */
    private void calcPriceForAttrValues(StoreProductRequest storeProductRequest, StoreProduct storeProduct) {
        // 设置商品成本价和市场价，成本价=sku配置的最低价，商品价格=sku配置的最高价格
        //        BigDecimal costPrice = storeProductRequest.getAttrValue()
        //                    .stream().map(e->e.getCost()).reduce(BigDecimal.ZERO,BigDecimal::add);
        // 不要显示成本价，显示最低sku售价
        double costPrice = storeProductRequest.getAttrValue().stream().mapToDouble(e -> e.getCost().doubleValue()).min().getAsDouble();

        //原成本价
        BigDecimal sourceCost = storeProductRequest.getSourceCost();

        double sellPrice = storeProductRequest.getAttrValue().stream().mapToDouble(e -> e.getPrice().doubleValue()).min().getAsDouble();
        //        BigDecimal sellPrice = storeProductRequest.getAttrValue()
        //                    .stream().map(e->e.getOtPrice()).reduce(BigDecimal.ZERO,BigDecimal::add);
        // 原价
        double otPrice = storeProductRequest.getAttrValue().stream().mapToDouble(e -> e.getOtPrice().doubleValue()).min().getAsDouble();

        int stock = storeProductRequest.getAttrValue().stream().mapToInt(e -> e.getStock()).sum();
        storeProduct.setCost(BigDecimal.valueOf(costPrice));
        storeProduct.setSourceCost(sourceCost);
        storeProduct.setPrice(BigDecimal.valueOf(sellPrice));
        storeProduct.setOtPrice(BigDecimal.valueOf(otPrice));
        storeProduct.setStock(stock);
    }

    /**
     * 计算产品属性之中最大和最小的价格，新增和编辑使用
     * @param attrValues 分析的参数
     * @param storeProduct 当前操作的产品
     */
    private void calcPriceForAttrValues(List<StoreProductAttrValue> attrValues, StoreProductResponse storeProduct) {
        // 设置商品成本价和市场价，成本价=sku配置的最低价，商品价格=sku配置的最高价格
        //        BigDecimal costPrice = storeProductRequest.getAttrValue()
        //                    .stream().map(e->e.getCost()).reduce(BigDecimal.ZERO,BigDecimal::add);
        // 不要显示成本价，显示最低sku售价
        //        int costPrice = storeProductRequest.getAttrValue()
        //                .stream().mapToInt(e->e.getCost().intValue()).max().getAsInt();

        double sellPrice = attrValues.stream().mapToDouble(e -> e.getPrice().doubleValue()).min().getAsDouble();
        //        BigDecimal sellPrice = storeProductRequest.getAttrValue()
        //                    .stream().map(e->e.getOtPrice()).reduce(BigDecimal.ZERO,BigDecimal::add);
        // 原价
        double otPrice = attrValues.stream().mapToDouble(e -> e.getOtPrice().doubleValue()).min().getAsDouble();

        int stock = attrValues.stream().mapToInt(e -> e.getStock()).sum();
        storeProduct.setPrice(BigDecimal.valueOf(sellPrice));
        storeProduct.setOtPrice(BigDecimal.valueOf(otPrice));
        storeProduct.setStock(stock);
    }

    /**已弃用
     * 推荐商品列表
     * @param brandId 品牌ID
     * @param limit 最大数据量
     * @return 推荐商品列表集
     */
	/*@Override
	public List<StoreProduct> getRecommendStoreProduct(Integer brandId, Integer limit) {
	    if (limit < 0 || limit > 20)
	        throw new CrmebException("获取推荐商品数量不合法 limit > 0 || limit < 20");
	    PageHelper.startPage(1, limit);
	    LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = new LambdaQueryWrapper<StoreProduct>();
	    lambdaQueryWrapper.eq(StoreProduct::getIsGood, false);
	    if (brandId != null) {
	        lambdaQueryWrapper.eq(StoreProduct::getBrandId, brandId);
	    }
	    lambdaQueryWrapper.orderByDesc(StoreProduct::getSort).orderByDesc(StoreProduct::getId);
	    return storeProductDAO.selectList(lambdaQueryWrapper);
	}*/

    /**
     *
     * @param productId 商品id
     * @return
     */
    @Override
    public Boolean deleteProduct(Integer productId) {
        LambdaUpdateWrapper<StoreProduct> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(StoreProduct::getId, productId);
        lambdaUpdateWrapper.set(StoreProduct::getIsDel, true);
        lambdaUpdateWrapper.set(StoreProduct::getIsEurope, 1);
        return update(lambdaUpdateWrapper);
    }

    /**
     * 恢复已删除的商品
     * @param productId 商品id
     * @return 恢复结果
     */
    @Override
    public boolean reStoreProduct(Integer productId) {
        LambdaUpdateWrapper<StoreProduct> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(StoreProduct::getId, productId);
        lambdaUpdateWrapper.set(StoreProduct::getIsDel, false);
        return update(lambdaUpdateWrapper);
    }

    ///////////////////////////////////////////自定义方法

    // 操作库存
    private boolean doProductStock(StoreProductStockRequest storeProductStockRequest) {
        StoreProduct existProduct = getById(storeProductStockRequest.getProductId());
        List<StoreProductAttrValue> existAttr = storeProductAttrValueService.getListByProductIdAndSkuId(storeProductStockRequest.getProductId(), storeProductStockRequest.getSourceSkuId());
        if (null == existProduct || null == existAttr) { // 为找到商品
            logger.info("库存修改任务未获取到商品信息" + JSON.toJSONString(storeProductStockRequest));
            return true;
        }
        boolean isPlus = storeProductStockRequest.getType().equals("add");
        int productStock = isPlus ? existProduct.getStock() + storeProductStockRequest.getNum() : existProduct.getStock() - storeProductStockRequest.getNum();
        existProduct.setStock(productStock);
        updateById(existProduct);
        for (StoreProductAttrValue attrValue : existAttr) {
            int stock = attrValue.getStock();
            int productAttrStock = isPlus ? attrValue.getStock() + storeProductStockRequest.getNum() : attrValue.getStock() - storeProductStockRequest.getNum();
            attrValue.setStock(productAttrStock);
            storeProductAttrValueService.update(Wrappers.<StoreProductAttrValue>lambdaUpdate()
                    .set(StoreProductAttrValue::getStock,productAttrStock)
                    .eq(StoreProductAttrValue::getProductId,attrValue.getProductId())
                    .eq(StoreProductAttrValue::getSourceSkuId,attrValue.getSourceSkuId())
            );
//            storeProductAttrValueService.updateById(attrValue);
            if(stock <= 0 && attrValue.getStock() > 0){
                ThreadPoolUtils.getThread().submit(() -> updateProductMinPrice(existProduct));
            }
        }
        //productSearchService.updateProductData(existProduct.getId());
        return true;
    }

    /**
     * 解析json字符串 返回对应对象的数据
     * @param storeProductRequest
     * @return
     */
    //    private List<StoreProductAttrValueRequest> getStoreProductAttrValueRequests(StoreProductRequest storeProductRequest) {
    //        List<StoreProductAttrValueRequest> storeProductAttrValuesRequest = new ArrayList<>();
    //        com.alibaba.fastjson.JSONArray attrJSONArray = com.alibaba.fastjson.JSONArray.parseArray(storeProductRequest.getAttrValue());
    //        for (int i = 0; i < attrJSONArray.size(); i++) {
    //            com.alibaba.fastjson.JSONObject jsonObject = attrJSONArray.getJSONObject(i);
    //            StoreProductAttrValueRequest attrValueRequest =
    //                    com.alibaba.fastjson.JSONObject.parseObject(String.valueOf(jsonObject), StoreProductAttrValueRequest.class);
    //            storeProductAttrValuesRequest.add(attrValueRequest);
    //        }
    //        return storeProductAttrValuesRequest;
    //    }

    /**
     * 产品保存和更新时设置attr和attrValues属性
     * @param storeProductRequest 产品属性
     * @return 设置后的数据对象
     */
    private HashMap<String, Object> setAttrValueByRequest(StoreProductRequest storeProductRequest) {
        HashMap<String, Object> attrValues = new HashMap<>();
        attrValues.put("attr", storeProductRequest.getAttr());
        attrValues.put("attrValue", storeProductRequest.getAttrValue());
        return attrValues;
    }
    //    public static void main(String[] args) throws IOException, JSONException {
    //        // 请求示例 url 默认请求参数已经做URL编码
    //        // 淘宝API
    //        String tbUrl = "https://api03.6bqb.com/taobao/detail?apikey=A5E94A9B7EBEBE9BB305680C0EE23885&itemid=16793826526";
    //        // 京东
    //        String jdUrl = "https://api03.6bqb.com/jd/detail?apikey=A5E94A9B7EBEBE9BB305680C0EE23885&itemid=10000017776";
    //        // 苏宁
    //        String snUrl = "https://api03.6bqb.com/suning/detail?apikey=A5E94A9B7EBEBE9BB305680C0EE23885&itemid=10750373914&shopid=0070088010";
    //        // 拼多多
    //        String pddUrl = "https://api03.6bqb.com/pdd/detail?apikey=A5E94A9B7EBEBE9BB305680C0EE23885&itemid=5914165983";
    //        CopyProduct cp = new CopyProduct();
    ////        JSONObject tbJson = cp.getRequestFromUrl(tbUrl);
    ////        System.out.println("淘宝产品"+tbJson.toString());
    ////        JSONObject jdJson = cp.getRequestFromUrl(jdUrl);
    ////        System.out.println("京东产品"+jdJson.toString());
    ////        JSONObject snJson = cp.getRequestFromUrl(snUrl);
    ////        System.out.println("苏宁产品"+snJson.toString());
    //        JSONObject pddJson = cp.getRequestFromUrl(pddUrl);
    //
    //        System.out.println("拼多多产品"+pddJson.toString());
    //
    //        cp.getTaobaoProductInfo("",0);
    //    }

    @Override
    public StoreProduct getByBarCode(String barCode) {
    	StoreProduct storeProduct = storeProductDAO.selectOne(Wrappers.<StoreProduct>lambdaQuery().eq(StoreProduct::getBarCode, barCode));
        // 匹配详情属性
        productConvertUtil.convertProduct(storeProduct);

        return storeProduct;
    }

    @Override
    public int reSortProduct() {
        return storeProductDAO.reSortProduct();
    }

    @Override
    public boolean updateIsBest(Integer productId, Boolean isBest) {
        if (productId == null) {
            return false;
        }
        boolean succ = this.update(Wrappers.<StoreProduct>lambdaUpdate().set(StoreProduct::getIsBest, isBest).eq(StoreProduct::getId, productId));
        //productSearchService.updateProductData(productId);
        return succ;
    }

    /**
     * 获取所有上架商品的品牌id
     * @return
     */
    @Override
    public List<Integer> getAllStoreProductBrand() {
        List<Integer> brandIdList = new ArrayList<>();
        LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(StoreProduct::getBrandId);
        lambdaQueryWrapper.eq(StoreProduct::getIsShow, 1);
        lambdaQueryWrapper.eq(StoreProduct::getIsDel, 0);
        lambdaQueryWrapper.groupBy(StoreProduct::getBrandId);
        List<StoreProduct> productList = storeProductDAO.selectList(lambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(productList)) {
            for (StoreProduct storeProduct : productList) {
                if (null != storeProduct && null != storeProduct.getBrandId()) {
                    brandIdList.add(storeProduct.getBrandId());
                }
            }
        }
        return brandIdList;
    }

//    /**
//     * 设置是否参加活动
//     *
//     * @param productId
//     * @param isPromoter
//     * @return
//     */
	/*@Override
	public boolean updateIsPromoter(Integer productId, Boolean isPromoter) {
	    if (productId == null) {
	        return false;
	    }
	    boolean succ = this.update(Wrappers.<StoreProduct>lambdaUpdate()
	    		.set(StoreProduct::getIsPromoter, isPromoter)
	    		.eq(StoreProduct::getId, productId)
	    		);
	    return succ;
	}*/

    @Override
    public PageInfo<StoreProductApiResponse> listProductByApi(ChannelMerchant channelMerchant, List<String> cateIds, List<String> filterCateIds,
            List<String> brandIds, String goodsName, String keyWord, Integer goodsId, Integer limitStock, Integer isShow, Integer pageNo, Integer pageSize) {
        // 处理可见品牌和供应商
        List<String> brands = JSON.parseArray(channelMerchant.getBrandIds(), String.class);
        if(CollectionUtils.isEmpty(brands)) {
            brands = brandIds;
        } else if(CollectionUtils.isNotEmpty(brandIds)) {
            brands = brands.stream().filter(item -> brandIds.contains(item)).collect(Collectors.toList());
        }

        // 查询平台加价率
        MarkupRateRequest markupRateQuery = new MarkupRateRequest();
        markupRateQuery.setMerId(channelMerchant.getId());
        markupRateQuery.setType(MarkupRateTypeEnum.PLAT_平台加价率.getType());
        BigDecimal rate = markupRateService.selectMerchantRatio(markupRateQuery).divide(new BigDecimal("100"));

        List<String> supplierss = JSON.parseArray(channelMerchant.getSuppliersIds(), String.class);
        List<String> tempIds = JSON.parseArray(channelMerchant.getTempId(), String.class);

        // 查询商品
        pageSize = 1000 < pageSize ? 1000 : pageSize;
        Page<Object> page = PageHelper.startPage(pageNo, pageSize);
        IndexStoreProductSearchRequest request = new IndexStoreProductSearchRequest();
        request.setBrandIdList(brands);
        request.setSuppliersIdList(supplierss);
        request.setTempIdList(tempIds);
        request.setCateIds(cateIds);
        request.setFilterCateIds(filterCateIds);
        request.setStoreName(goodsName);
        request.setKeywords(keyWord);
        request.setId(goodsId);
        request.setLimitStock(limitStock);
        request.setIsShow(isShow);

        List<StoreProductApiResponse> products = storeProductDAO.selectApiProductList(request);
        if(CollectionUtils.isEmpty(products)) {
            return CommonPage.copyPageInfo(page, new ArrayList<StoreProductApiResponse>());
        }
        // 匹配详情属性
        productConvertUtil.convertProductApi(products);
        List<Integer> ids = products.stream().map(StoreProductApiResponse::getId).collect(Collectors.toList());
        // 查询商品规格
        List<StoreProductAttrValue> productAttrValues = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery()
                .in(StoreProductAttrValue :: getProductId, ids)
                );
        Map<Integer, List<StoreProductAttrValueApiResponse>> attrValueMap = productAttrValues.stream().collect(Collectors.toMap(StoreProductAttrValue :: getProductId,
                s ->  {
                List<StoreProductAttrValueApiResponse> list = new ArrayList<StoreProductAttrValueApiResponse>();
                StoreProductAttrValueApiResponse response = new StoreProductAttrValueApiResponse();
                BeanUtils.copyProperties(s, response);
                list.add(response);
                return list;
                },
                (List<StoreProductAttrValueApiResponse> value1, List<StoreProductAttrValueApiResponse> value2) -> {
                    value1.addAll(value2);
                    return value1;
                }
            ));

        // 赋值
        // 分类获取头程
        List<Integer> cateId = products.stream().map(StoreProductApiResponse::getCateId).distinct().collect(Collectors.toList());
        Map<Integer, CategoryMatch> categoryMatchMap = categoryMatchService.getByIds(cateId).stream().collect(Collectors.toMap(CategoryMatch::getId, e -> e, (v1, v2) -> v1));
        for(StoreProductApiResponse productResponse : products) {
            List<StoreProductAttrValueApiResponse> attrValues = attrValueMap.get(productResponse.getId());
            productResponse.setAttrValue(attrValues);
            // 加价计算
            if(25 == channelMerchant.getId()) {
                productResponse.setPrice(productResponse.getPrice().divide(new BigDecimal("8"), 0, BigDecimal.ROUND_DOWN));
            } else {
                productResponse.setPrice(productResponse.getPrice().add(PriceUtil.calePrice(productResponse.getPrice(), rate.toString())));
            }
            //是否包邮
            boolean freeShipping = priceUtil.freeShipping(productResponse.getSuppliersId(), channelMerchant.getId());
            //首段物流费
//            BigDecimal firstPrice = priceUtil.getFirstPrice(productResponse.getIsEurope(), productResponse.getTempId(),channelMerchant,freeShipping,productResponse.getSuppliersName());
            BigDecimal firstPrice = priceUtil.getFirstPriceNew(productResponse.getIsEurope(), productResponse.getTempId(), AreaTypeEnum.CN.getType(), channelMerchant, freeShipping, categoryMatchMap.get(productResponse.getCateId()), productResponse.getSuppliersId());
            productResponse.setPrice(productResponse.getPrice().add(firstPrice));
            StoreProduct storeProduct = storeProductDAO.selectById(productResponse.getId());
            if(!CollectionUtils.isEmpty(attrValues)) {
                for(StoreProductAttrValueApiResponse attrValue : attrValues) {
                    if(25 == channelMerchant.getId()) {
                        attrValue.setPrice(attrValue.getPrice().divide(new BigDecimal("8"), 0, BigDecimal.ROUND_DOWN));
                    } else {
                        attrValue.setPrice(attrValue.getPrice().add(PriceUtil.calePrice(attrValue.getPrice(), rate.toString())));
                    }
                    attrValue.setPrice(attrValue.getPrice().add(firstPrice));
                    attrValue.setTaxPrice(priceUtil.getTaxPriceNew(storeProduct,AreaTypeEnum.CN.getType(),
                            attrValue.getPrice().add(firstPrice),channelMerchant,attrValue.getPrice(),freeShipping,false,true));
                    attrValue.setFreightPrice(priceUtil.getFirstPriceNew(productResponse.getIsEurope(),productResponse.getTempId(),AreaTypeEnum.CN.getType(),channelMerchant,freeShipping,categoryMatchMap.get(productResponse.getCateId()),productResponse.getSuppliersId()));
                }
            }
            productResponse.setCost(BigDecimal.ZERO);
        }

        return CommonPage.copyPageInfo(page, products);
    }

    @Override
    public StoreProductApiResponse getProductByApi(ChannelMerchant channelMerchant, String barCode) {
        // 处理可见品牌和供应商
        List<String> brands = JSON.parseArray(channelMerchant.getBrandIds(), String.class);
        List<String> supplierss = JSON.parseArray(channelMerchant.getSuppliersIds(), String.class);
        // 查询平台加价率
        MarkupRateRequest markupRateQuery = new MarkupRateRequest();
        markupRateQuery.setMerId(channelMerchant.getId());
        markupRateQuery.setType(MarkupRateTypeEnum.PLAT_平台加价率.getType());
        BigDecimal rate = markupRateService.selectMerchantRatio(markupRateQuery).divide(new BigDecimal("100"));

        // 查询商品
        IndexStoreProductSearchRequest request = new IndexStoreProductSearchRequest();
        request.setBrandIdList(brands);
        request.setSuppliersIdList(supplierss);
        request.setBarCode(barCode);

        List<StoreProductApiResponse> products = storeProductDAO.selectApiProductList(request);
        if(CollectionUtils.isEmpty(products)) {
            return null;
        }
        // 匹配详情属性
        productConvertUtil.convertProductApi(products);
        // 查询商品规格
        StoreProductApiResponse product = products.get(0);
        //商品是否包邮
        boolean freeShipping = priceUtil.freeShipping(product.getSuppliersId(), channelMerchant.getId());
        CategoryMatch categoryMatch = categoryMatchService.getById(product.getCateId());
        BigDecimal firstPrice = priceUtil.getFirstPriceNew(product.getIsEurope(),product.getTempId(),AreaTypeEnum.CN.getType(),channelMerchant,freeShipping,categoryMatch,product.getSuppliersId());
        List<StoreProductAttrValue> productAttrValues = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery()
                .eq(StoreProductAttrValue :: getProductId, product.getId())
                );
        Map<Integer, List<StoreProductAttrValueApiResponse>> attrValueMap = productAttrValues.stream().collect(Collectors.toMap(StoreProductAttrValue :: getProductId,
                s ->  {
                    List<StoreProductAttrValueApiResponse> list = new ArrayList<StoreProductAttrValueApiResponse>();
                    StoreProductAttrValueApiResponse response = new StoreProductAttrValueApiResponse();
                    BeanUtils.copyProperties(s, response);
                    list.add(response);
                    return list;
                },
                (List<StoreProductAttrValueApiResponse> value1, List<StoreProductAttrValueApiResponse> value2) -> {
                    value1.addAll(value2);
                    return value1;
                }
                ));

        // 赋值
        List<StoreProductAttrValueApiResponse> attrValues = attrValueMap.get(product.getId());
        product.setAttrValue(attrValues);
        // 加价计算
        if(25 == channelMerchant.getId()) {
            product.setPrice(product.getPrice().divide(new BigDecimal("8"), 0, BigDecimal.ROUND_DOWN));
        } else {
            product.setPrice(product.getCost().add(PriceUtil.calePrice(product.getCost(), rate.toString())));
        }
        product.setPrice(product.getPrice().add(firstPrice));
        if(!CollectionUtils.isEmpty(attrValues)) {
            for(StoreProductAttrValueApiResponse attrValue : attrValues) {
                if(25 == channelMerchant.getId()) {
                    attrValue.setPrice(attrValue.getPrice().divide(new BigDecimal("8"), 0, BigDecimal.ROUND_DOWN));
                } else {
                    attrValue.setPrice(product.getCost().add(PriceUtil.calePrice(product.getCost(), rate.toString())));
                }
                attrValue.setPrice(attrValue.getPrice().add(firstPrice));
                Supplier productSupplier = supplierService.getById(product.getSuppliersId());
                StoreProduct storeProduct = storeProductDAO.selectById(product.getId());
                attrValue.setFreightPrice(priceUtil.getSecondPriceNew(storeProduct,AreaTypeEnum.CN.getType(),channelMerchant,freeShipping,productSupplier.getId(),
                        attrValue.getWeight(), productSupplier.getDirectMailType(),   attrValue.getPrice(),attrValue.getSourceSkuId(),null));

                attrValue.setTaxPrice(priceUtil.getTaxPriceNew(storeProduct, AreaTypeEnum.CN.getType(),
                        attrValue.getPrice().add(firstPrice), channelMerchant, attrValue.getPrice(),freeShipping,false,true));
                }
        }
        product.setCost(BigDecimal.ZERO);

        return product;
    }

    @Override
    public List<StoreProduct> selectProductList(IndexStoreProductSearchRequest request,PageParamRequest pageParamRequest) {
        queryCondition(request);
//        request.setEurToRmbRate(PriceUtil.DEFAULT_EXCHANGE_RATE_EUR);
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<StoreProduct> storeProducts = storeProductDAO.selectProductList(request);
        // 匹配详情属性
        productConvertUtil.convertProduct(storeProducts);

        return storeProducts;
    }

    /**
     *
     * @author cyz
     * @date 2021/4/9 11:25
     * @param request
     * @param pageParamRequest
     * @return com.github.pagehelper.PageInfo<com.zbkj.crmeb.store.response.StoreProductResponse>
     */
    @Override
    public PageInfo<StoreProductResponse> selectZoneProductList(ProductRequest request,PageParamRequest pageParamRequest) {
        if(request.getMerId() != 0){
            ChannelMerchant channelMerchant = channelMerchantService.getById(request.getMerId());
            List<String> brandIdsList= JSON.parseArray(channelMerchant.getBrandIds(), String.class);
            List<String> suppliersIdList = JSON.parseArray(channelMerchant.getSuppliersIds(), String.class);
            List<String> tempIdList = JSON.parseArray(channelMerchant.getTempId(), String.class);
            if (CollectionUtils.isNotEmpty(suppliersIdList)) {
                Supplier supplier = supplierService.getSupplierBarcode(request.getMerId());
                if (null != supplier) {
                    //商户如果是供应商的话 查询商户自建的商品 默认传入商户配置的供应商id
                    suppliersIdList.add(supplier.getId().toString());
                }
            }
            request.setBrandIdList(brandIdsList).setSuppliersIdList(suppliersIdList).setTempIdList(tempIdList);
            request.setTableNameMp(TableNameUtil.getProductMerName(request.getMerId()));
        }
        request.setShowIds(null);
        if (StringUtils.isNotBlank(request.getCids())){
            request.setCateIdList( Arrays.asList(request.getCids().split(",")));
        }
        Page<StoreProduct> storeProductPage = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<StoreProduct> storeProductList = storeProductDAO.selectZoneProductList(request);
        if(CollectionUtils.isEmpty(storeProductList)) {
            return CommonPage.copyPageInfo(storeProductPage, new ArrayList<>());
        }
        // 匹配详情属性
        productConvertUtil.convertProduct(storeProductList);
        List<Integer> collect = new ArrayList<>();
        Map<Integer, StoreProductMer> storeProductMerMap = null;
        if(request.getMerId() != 0){
            List<Integer> productIdList = storeProductList.stream().map(StoreProduct::getId).collect(Collectors.toList());
            //查询商户下架商品
            List<StoreProductMer> productMerList = storeProductMerService.list(Wrappers.lambdaQuery(StoreProductMer.class).in(StoreProductMer::getProductId, productIdList)
                    .eq(StoreProductMer::getIsNotShow, 1)
                    );
            collect = productMerList.stream().map(StoreProductMer::getProductId).collect(Collectors.toList());
            storeProductMerMap = priceUtil.calcProductPrice(storeProductList,request.getMerId(), AreaTypeEnum.CN.getType());
        }
        List<Integer> brandIdList = storeProductList.stream().map(StoreProduct::getBrandId).collect(Collectors.toList());
        Map<Integer, String> brandMap = new HashMap<>();
        if(CollectionUtils.isNotEmpty(brandIdList)){
            brandMap = storeBrandService.list(Wrappers.lambdaQuery(StoreBrand.class).in(StoreBrand::getId,brandIdList)).stream().collect(HashMap::new, (n, v) -> n.put(v.getId(), v.getLogo()), HashMap::putAll);
        }
        List<Integer> ids = storeProductList.stream().map(StoreProduct::getId).collect(Collectors.toList());
        // 处理attrvalue数据
        List<StoreProductAttrValue> attrValues = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery()
                .in(StoreProductAttrValue :: getProductId, ids)
        );
        if (CollectionUtils.isEmpty(attrValues)){
            return  null;
        }
        Map<Integer, List<StoreProductAttrValue>> attrValueMap = attrValues.stream().collect(Collectors.groupingBy(StoreProductAttrValue::getProductId));
        // 循环赋值
        List<StoreProductResponse> storeProductResponses = new ArrayList<>();
        for (StoreProduct product : storeProductList) {
            Integer id = product.getId();
            StoreProductResponse storeProductResponse = new StoreProductResponse();
            BeanUtils.copyProperties(product, storeProductResponse);
            // 通过原价算折扣率 ----处理
            if (storeProductResponse.getOtPrice() != null && storeProductResponse.getOtPrice().intValue() > 0) {
                BigDecimal bigDecimal = priceUtil.calcDiscount(storeProductResponse.getPrice(), storeProductResponse.getOtPrice(), storeProductResponse.getExchangeRate());
                if (null != bigDecimal) {
                    storeProductResponse.setDiscount(bigDecimal.toString() + "折");
                }
            }
            storeProductResponse.setMerIsShow(collect.contains(storeProductResponse.getId()) ? 0 : 1);
            storeProductResponse.setBrandImage(brandMap.get(product.getBrandId()));
            List<StoreProductAttrValue> values = attrValueMap.get(id);
            if(CollectionUtils.isNotEmpty(values)){
                if(request.getMerId() != 0){
                    priceUtil.calcProductValuePrice(values, request.getMerId(), product,AreaTypeEnum.CN.getType(), storeProductMerMap,false, null,true,null);
                }
                List<StoreProductAttrValueResponse> valueResponses = new ArrayList<>();
                for(StoreProductAttrValue value : values) {
                    StoreProductAttrValueResponse valueResponse = new StoreProductAttrValueResponse();
                    BeanUtils.copyProperties(value, valueResponse);
                    valueResponses.add(valueResponse);
                }
                storeProductResponse.setAttrValue(valueResponses);
            }
            storeProductResponses.add(storeProductResponse);
        }
        return CommonPage.copyPageInfo(storeProductPage, storeProductResponses);
    }

    @Override
    public List<ProductExcelVo> getExprotList(StoreProductSearchRequest request, PageParamRequest pageParamRequest) {
        LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = getQueryWrapper(request);
        String sqlStr = MybatisPlusUtil.getSqlStr(lambdaQueryWrapper);
        logger.info("导出sql查询条件:"+sqlStr);
        String sqlSegment = lambdaQueryWrapper.getSqlSegment();
        HashMap<String, Object> ew = new HashMap<String, Object>() {{
            put("paramNameValuePairs", lambdaQueryWrapper.getParamNameValuePairs());
        }};
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<ProductExcelVo> list = storeProductDAO.selectExportList(sqlSegment, ew);
        // 匹配详情属性
        productConvertUtil.convertProductExcel(list);
        list.forEach(productExcelVo -> {
            // 通过原价算折扣率 ----处理
            if (productExcelVo.getAttrOtPrice() != null && productExcelVo.getAttrOtPrice().intValue() > 0) {
                BigDecimal bigDecimal = priceUtil.calcDiscount(productExcelVo.getAttrPrice(), productExcelVo.getAttrOtPrice(), productExcelVo.getExchangeRate());
                if (null != bigDecimal) {
                    productExcelVo.setPriceDiscount(bigDecimal + "折");
                }
                BigDecimal costDiscount = priceUtil.calcDiscount(productExcelVo.getAttrCost(), productExcelVo.getAttrOtPrice(), productExcelVo.getExchangeRate());
                if (null != costDiscount) {
                    productExcelVo.setDiscount(costDiscount + "折");
                }
            }
        });
        return list;
    }

    private LambdaQueryWrapper<StoreProduct> getQueryWrapper(StoreProductSearchRequest request) {
        //带 StoreProduct 类的多条件查询
        LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        List<Integer> merIds = systemAdminService.getAdminMerIds();
        //类型搜索
        switch (request.getType()) {
            case 1:
                //出售中（已上架）
                lambdaQueryWrapper.eq(StoreProduct::getIsShow, true);
                lambdaQueryWrapper.eq(StoreProduct::getIsDel, false);
                // 库存为0的商品不显示在出售中列表
                lambdaQueryWrapper.gt(StoreProduct::getStock, 0);
                break;
            case 2:
                //仓库中（未上架）
                lambdaQueryWrapper.eq(StoreProduct::getIsShow, false);
                lambdaQueryWrapper.eq(StoreProduct::getIsDel, false);
                break;
            case 3:
                //已售罄
                lambdaQueryWrapper.le(StoreProduct::getStock, 0);
                lambdaQueryWrapper.eq(StoreProduct::getIsDel, false);
                break;
            case 4:
                //警戒库存
                Integer stock = Integer.parseInt(systemConfigService.getValueByKey("store_stock"));
                lambdaQueryWrapper.le(StoreProduct::getStock, stock);
                lambdaQueryWrapper.gt(StoreProduct::getStock, 0);
                lambdaQueryWrapper.eq(StoreProduct::getIsDel, false);
                break;
            case 5:
                //回收站
                lambdaQueryWrapper.eq(StoreProduct::getIsDel, true);
                break;
            case 6:
                //自建待审核
                lambdaQueryWrapper.eq(StoreProduct::getSelfPushStatus,1);
                break;
            default:
                break;
        }
        //自建商品二手/新品查询
        if (Objects.equals(ProductTypeEnum.INSIDE.getCode(),request.getIsEurope())){
            if (Objects.equals(1,request.getOrderType())){
                lambdaQueryWrapper.and(i -> i.or().isNull(StoreProduct::getDegree).or().eq(StoreProduct::getDegree,""));
            }
            if (Objects.equals(3,request.getOrderType())){
                lambdaQueryWrapper.isNotNull(StoreProduct::getDegree).ne(StoreProduct::getDegree,"");
            }
        }
        if (request.isSellingBelowCost()) {
            lambdaQueryWrapper.apply(" price < cost ");
        }
        if(StringUtils.isNotBlank(request.getDateLimit())){
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(request.getDateLimit());
            lambdaQueryWrapper.between(StoreProduct::getCreateTime,dateLimit.getStartTime(),dateLimit.getEndTime());
        }

        //关键字搜索
        if (!StringUtils.isBlank(request.getKeywords())) {
            lambdaQueryWrapper.and(i -> i.or()
            		.eq(NumberUtil.isInteger(request.getKeywords()),StoreProduct::getId, request.getKeywords())
            		.or().like(StoreProduct::getStoreName, request.getKeywords())
//            		.or().like(StoreProduct::getStoreInfo, request.getKeywords())
            		.or().like(StoreProduct::getKeyword, request.getKeywords())
//            		.or().like(StoreProduct::getBarCode, request.getKeywords())
            		);
        }
        if (BooleanUtil.isTrue(request.getIsBest())) {
            lambdaQueryWrapper.eq(StoreProduct::getIsBest, true);
        }
        //判断是否供应商筛选
        if (request.getSupplierId() != null) {
            lambdaQueryWrapper.eq(StoreProduct::getSuppliersId, request.getSupplierId());
        }
        if(CollectionUtils.isNotEmpty(request.getSupplierIds())){
            lambdaQueryWrapper.in(StoreProduct::getSuppliersId,request.getSupplierIds());
        }
        if (CollectionUtils.isNotEmpty(request.getMerId())) {
            lambdaQueryWrapper.in(StoreProduct::getMerId, request.getMerId());
        }
        if (CollectionUtils.isNotEmpty(request.getStockAreas())) {
            lambdaQueryWrapper.in(StoreProduct::getTempId, request.getStockAreas());
        }
        if (StringUtils.isNotBlank(request.getBrandId())) {
            lambdaQueryWrapper.eq(StoreProduct::getBrandId, request.getBrandId());
        }
        if(CollectionUtils.isNotEmpty(request.getBrandIds())){
            lambdaQueryWrapper.in(StoreProduct::getBrandId,request.getBrandIds());
        }
        // bug
        if (StringUtils.isNotBlank(request.getCateId())) {
            List<Integer> cateIds = categoryMatchService.getThreeChildVoListByPid(Integer.parseInt(request.getCateId())).stream().map(CategoryMatch::getId).collect(Collectors.toList());
            lambdaQueryWrapper.in(StoreProduct::getCateId, cateIds);
        }
        if(CollectionUtils.isNotEmpty(request.getCateIds())){
            List<Integer> cateIds = new ArrayList<>();
            request.getCateIds().forEach(cateId->cateIds.addAll(categoryMatchService.getThreeChildVoListByPid(cateId).stream().map(CategoryMatch::getId).collect(Collectors.toList())));
            lambdaQueryWrapper.in(StoreProduct::getCateId, cateIds);
        }
        if (StringUtils.isNotBlank(request.getZoneId())){
            List<StoreZoneProduct> storeZoneProduct = storeZoneProductService.list(Wrappers.<StoreZoneProduct>lambdaQuery().eq(StoreZoneProduct::getZoneId,request.getZoneId()));
            List<Integer> productIds = storeZoneProduct.stream().map(StoreZoneProduct::getProductId).distinct().collect(Collectors.toList());
            productIds.add(0);
            lambdaQueryWrapper.in(StoreProduct::getId, productIds);
        }
        //会员折扣商品搜索
        if(BooleanUtil.isTrue(request.getMemberDiscountFlag())) {
            lambdaQueryWrapper.inSql(StoreProduct::getId, "SELECT product_id FROM eb_store_product_discount WHERE mer_id = " + request.getMerchantId());
        }

        //新增条件最低高价格 最大小库存
        if(request.getMinPrice() !=null && request.getMaxPrice() == null){
            lambdaQueryWrapper.ge(StoreProduct::getPrice,request.getMinPrice());
        }else if(request.getMinPrice() == null && request.getMaxPrice() != null){
            lambdaQueryWrapper.le(StoreProduct::getPrice,request.getMaxPrice());
        }else if(request.getMinPrice() !=null && request.getMaxPrice() != null){
            lambdaQueryWrapper.between(StoreProduct::getPrice,request.getMinPrice(),request.getMaxPrice());
        }
        if(request.getMinStock() !=null && request.getMaxStock() == null){
            lambdaQueryWrapper.ge(StoreProduct::getStock,request.getMinStock());
        }else if(request.getMinStock() == null && request.getMaxStock() != null){
            lambdaQueryWrapper.le(StoreProduct::getStock,request.getMaxStock());
        }else if(request.getMinStock() !=null && request.getMaxStock() != null){
            lambdaQueryWrapper.between(StoreProduct::getStock,request.getMinStock(),request.getMaxStock());
        }
        //自建
        if (null != request.getIsEurope()) {
            lambdaQueryWrapper.eq(StoreProduct::getIsEurope, ProductTypeEnum.INSIDE);
            lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(merIds), StoreProduct :: getMerId, merIds);
            //自建商品推送状态
            if(request.getSelfPushStatus() != null){
                lambdaQueryWrapper.eq(StoreProduct::getSelfPushStatus,request.getSelfPushStatus());
            }
            // 导出有问题
//            lambdaQueryWrapper.eq(StoreProduct :: getIsEurope, ProductTypeEnum.INSIDE.getCode()).isNull(StoreProduct::getConvertIsEurope);
//            lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(merIds), StoreProduct :: getMerId, merIds);
        }
        if (null != request.getSeasonCode()) {
        	if("-1".equals(request.getSeasonCode())) {
        		lambdaQueryWrapper.isNull(StoreProduct :: getSeasonCode);
        	} else {
        		lambdaQueryWrapper.likeRight(StoreProduct :: getSeasonCode, request.getSeasonCode());
        	}
        }
        if (null != request.getIsNorm()) {
            if(request.getIsNorm()) {
                lambdaQueryWrapper.isNotNull(StoreProduct :: getNormId);
            } else if(!request.getIsNorm()) {
                lambdaQueryWrapper.isNull(StoreProduct :: getNormId);
            }
        }
        //云仓
        if(CollectionUtils.isNotEmpty(request.getIsNotEurope())) {
            lambdaQueryWrapper.and(e->e.notIn(StoreProduct :: getIsEurope, request.getIsNotEurope())
                    .or(i->i.eq(StoreProduct::getIsEurope,1).isNotNull(StoreProduct::getConvertIsEurope)));
//            lambdaQueryWrapper.notIn(StoreProduct :: getIsEurope, request.getIsNotEurope());
        }
        if(StringUtils.isNotBlank(request.getNormKeywords())){
            lambdaQueryWrapper.inSql(StoreProduct::getNormId,"SELECT id from eb_store_product_norm where keyword like '%"+request.getNormKeywords()+"%'");
        }

        if (ObjectUtils.isNotEmpty(request.getCreateTimeStart()) && ObjectUtils.isNotEmpty(request.getCreateTimeEnd())){
            lambdaQueryWrapper.between(StoreProduct::getCreateTime, DateUtil.strToDate(request.getCreateTimeStart(),Constants.DATE_FORMAT_DATE).getTime()/1000,DateUtil.strToDate(request.getCreateTimeEnd(),Constants.DATE_FORMAT_DATE).getTime()/1000);
        }
        if(CollectionUtils.isNotEmpty(request.getPickingIds())){
            //查sku存在的商品
            lambdaQueryWrapper.inSql(StoreProduct::getId,"SELECT DISTINCT v.product_id FROM eb_store_product_picking p LEFT JOIN eb_store_product_attr_value v on p.sku_id = v.source_sku_id where p.picking_id in "+request.getPickingIds().toString().replace("[","(").replace("]",")"));
        }
        if(CollectionUtils.isNotEmpty(request.getActivityIds())){
            lambdaQueryWrapper.inSql(StoreProduct::getId,"SELECT DISTINCT a.product_id FROM eb_store_product_activity a LEFT JOIN eb_store_product b on a.product_id = b.id where a.activity_id in "+request.getActivityIds().toString().replace("[","(").replace("]",")"));
        }
        //折扣查询
        if (request.getMinDiscount() != null && request.getMaxDiscount() == null){
            lambdaQueryWrapper.apply("CEILING( source_cost / (ot_price * exchange_rate)*100) / 10 >= {0} ",request.getMinDiscount());
        }else if(request.getMinDiscount() == null && request.getMaxDiscount() != null){
            lambdaQueryWrapper.apply("CEILING( source_cost / (ot_price * exchange_rate)*100) / 10 <= {0} ",request.getMaxDiscount());
        }else if(request.getMinDiscount() != null && request.getMaxDiscount() != null){
            lambdaQueryWrapper.apply("CEILING( source_cost / (ot_price * exchange_rate)*100) / 10 BETWEEN  {0} and {1} ",request.getMinDiscount(), request.getMaxDiscount());
        }
//        lambdaQueryWrapper.orderByDesc(StoreProduct::getId);
        // 成本价折扣排序
        if (request.getCostSort() != null) {
            String value = request.getCostSort() == 0 ? "ASC" : "DESC";
            lambdaQueryWrapper.last("ORDER BY CEILING( source_cost / (ot_price * exchange_rate)*100) / 10 " + value );
        } else {
            //mod by cdm 2023/07/24 修改默认排序，按创建时间降序
            lambdaQueryWrapper.orderByDesc(StoreProduct::getId);
           // lambdaQueryWrapper.orderByDesc(StoreProduct::getLastPushTime);
            //lambdaQueryWrapper.orderByDesc(StoreProduct::getId);
        }
        //selfSourceSkuId
        if(StringUtils.isNotBlank(request.getSelfSourceSkuId())){
            lambdaQueryWrapper.inSql(StoreProduct::getId,"SELECT DISTINCT product_id FROM eb_store_product_attr_value  where self_source_sku_id like '"+request.getSelfSourceSkuId().toString()+"%'");
        }
        // 商品自增ID不为空
        if (CollectionUtils.isNotEmpty(request.getProductAutoIds())){
            lambdaQueryWrapper.in(StoreProduct::getId,request.getProductAutoIds());
        }


        return lambdaQueryWrapper;
    }

    private StoreProductQueryDto getStoreProductQueryV2(StoreProductSearchRequest request) {
        //带 StoreProduct 类的多条件查询
        List<Integer> merIds = systemAdminService.getAdminMerIds();
        StoreProductQueryDto queryDto = new StoreProductQueryDto();
        BeanUtils.copyProperties(request, queryDto);
        queryDto.setMerIds(merIds);
        //类型搜索
        switch (request.getType()) {
            case 4:
                //警戒库存
                Integer stock = Integer.parseInt(systemConfigService.getValueByKey("store_stock"));
                queryDto.setStock(stock);
                break;
            default:
                break;
        }

        if (request.isSellingBelowCost()) {
            queryDto.setSellingBelowCost(SwitchEnum.OPEN.getCode());
        }
        if(StringUtils.isNotBlank(request.getDateLimit())){
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(request.getDateLimit());
            queryDto.setCreateTimeGe(dateLimit.getStartTime());
            queryDto.setCreateTimeLe(dateLimit.getEndTime());
        }
        if (BooleanUtil.isTrue(request.getIsBest())) {
            queryDto.setIsBest(SwitchEnum.OPEN.getCode());
        }


        if (CollectionUtils.isNotEmpty(request.getMerId())) {
            queryDto.setMerIdList(request.getMerId());
        }

        if (StringUtils.isNotBlank(request.getCateId())) {
            List<Integer> cateIds = categoryMatchService.getThreeChildVoListByPid(Integer.parseInt(request.getCateId())).stream().map(CategoryMatch::getId).collect(Collectors.toList());
            queryDto.setCateIdFirstList(cateIds);
        }
        if(CollectionUtils.isNotEmpty(request.getCateIds())){
            List<Integer> cateIds = new ArrayList<>();
            request.getCateIds().forEach(cateId->cateIds.addAll(categoryMatchService.getThreeChildVoListByPid(cateId).stream().map(CategoryMatch::getId).collect(Collectors.toList())));
            queryDto.setCateIds(cateIds);
        }
        if (StringUtils.isNotBlank(request.getZoneId())){
            List<StoreZoneProduct> storeZoneProduct = storeZoneProductService.list(Wrappers.<StoreZoneProduct>lambdaQuery().eq(StoreZoneProduct::getZoneId,request.getZoneId()));
            List<Integer> productIds = storeZoneProduct.stream().map(StoreZoneProduct::getProductId).distinct().collect(Collectors.toList());
            productIds.add(0);
            queryDto.setProductIds(productIds);
        }
        //会员折扣商品搜索
        if(BooleanUtil.isTrue(request.getMemberDiscountFlag())) {
            queryDto.setMemberDiscountFlag(SwitchEnum.OPEN.getCode());

            queryDto.setMerchantId(request.getMerchantId());
        }
        if(NumberUtil.isInteger(request.getKeywords())){
            queryDto.setKeywordsInt(Integer.valueOf(request.getKeywords()));
        }

        //新增条件最低高价格 最大小库存
        queryDto.setMinPrice(request.getMinPrice());
        queryDto.setMaxPrice(request.getMaxPrice());
        queryDto.setMinStock(request.getMinStock());
        queryDto.setMaxStock(request.getMaxStock());

        if (null != request.getIsNorm()) {
            if(request.getIsNorm()) {
                queryDto.setIsNorm(SwitchEnum.OPEN.getCode());
            } else if(!request.getIsNorm()) {
                queryDto.setIsNorm(SwitchEnum.CLOSE.getCode());
            }
        }
        if(StringUtils.isNotBlank(request.getBrandId()) && NumberUtil.isInteger(request.getBrandId())){
            queryDto.setBrandIdInt(Integer.valueOf(request.getBrandId()));
        }

        // 商品自增ID不为空
        if (CollectionUtils.isNotEmpty(request.getProductAutoIds())){
            List<Integer> productAutoIdsInt = request.getProductAutoIds().stream()
                    .filter(s -> NumberUtil.isInteger(s)).map(v -> {
                        return Integer.valueOf(v);
                    }).collect(Collectors.toList());
            queryDto.setProductAutoIdsInt(productAutoIdsInt);
        }
        if (ObjectUtils.isNotEmpty(request.getCreateTimeStart()) && ObjectUtils.isNotEmpty(request.getCreateTimeEnd())){
            queryDto.setCreateTimeStart(String.valueOf(DateUtil.strToDate(request.getCreateTimeStart(),Constants.DATE_FORMAT_DATE).getTime()/1000));
            queryDto.setCreateTimeEnd(String.valueOf(DateUtil.strToDate(request.getCreateTimeEnd(),Constants.DATE_FORMAT_DATE).getTime()/1000));
        }

        return queryDto;
    }

    /**
     * 商品列表 - 查询条件
     * @param request
     * @param
     */
    private void queryCondition(IndexStoreProductSearchRequest request) {

        request.setIsShow(1);
        //搜索关键词
        String keywords = request.getKeywords();
        if (StringUtils.isNotBlank(keywords)) {
            List<String> keywordList = new ArrayList<>();
            int index = keywords.indexOf(" ");
            if(index == -1){
                keywordList.add(keywords);
            }else {
                String [] keywordarr = keywords.split("\\s+");
                for (String key : keywordarr){
                    keywordList.add(key);
                }
            }
            request.setKeywordList(keywordList);
        }

        //意大利轮播图-商品列表
        if (BooleanUtil.isTrue(request.getIsEurope())) {
            request.setIsEuropeInt(ProductTypeEnum.EUROPE.getCode());
        }

        //易时尚轮播图-商品列表
        if (BooleanUtil.isTrue(request.getMerUse())) {
            request.setMerUseInt(1);
        }

        //发货地
        if (request.getStockArea() != null && StringUtils.isNotBlank(request.getStockArea())) {
            List<String> stockAreaList = Arrays.asList(request.getStockArea().split(","));
            request.setStockAreaList(stockAreaList);
        }

        //图搜BarCode
        if (null != request.getBarCodeArr() && request.getBarCodeArr().size() > 0) {
            request.setBarCodeArr(request.getBarCodeArr());
        }

        //精选/小编推荐
        if (request.getIsBest() != null) {
            request.setIsBestInt(1);
            request.setOrder("esp.best_time desc");
        }

        //热卖
        if (request.getIsHot() != null) {
            request.setIsHotInt(1);
        }

        //新品
        if (request.getIsNew() != null) {
            request.setIsNewInt(1);
        }

        //优惠
        if (request.getIsBenefit() != null) {
            request.setIsBenefitInt(1);
        }

        //品牌
        if (request.getBrandId() != null) {
            request.setBrandId(request.getBrandId());
        }
        if (request.getBrandIds() != null && StringUtils.isNotBlank(request.getBrandIds())) {
            List<String> brandIdList = Arrays.asList(request.getBrandIds().split(","));;
            request.setBrandIdList(brandIdList);
        }

        //价格排序
        if (StringUtils.isNotBlank(request.getKeywords())) {
                request.setOrder("esp.brand_id DESC,esp.keyword DESC,esp.store_name DESC,esp.cate_id DESC");
        }

        //价格排序
        if (!StringUtils.isBlank(request.getPriceOrder())) {
            if (request.getPriceOrder().equals(Constants.SORT_DESC)) {
                request.setOrder("esp.price desc");
            } else {
                request.setOrder("esp.price asc");
            }
        }

        //销量排序
        if (!StringUtils.isBlank(request.getSalesOrder())) {
            if (request.getSalesOrder().equals(Constants.SORT_DESC)) {
                request.setOrder("esp.sales desc");
            } else {
                request.setOrder("esp.sales asc");
            }
        }

    }

    private String getProductBarCode(){
        String barCode = "";
        ProductRequest request = new ProductRequest();
        request.setMinBarCode(1001000000);
        request.setMaxBarCode(1001999999);
        StoreProduct storeProduct = storeProductDAO.selectProductOne(request);
        if(null == storeProduct){
            barCode = "1001000000";
        }else{
            Integer code = Integer.valueOf(storeProduct.getBarCode()) + 1;
            barCode = code.toString();
        }
        log.info("自建商品生成barCode:{}",barCode);
        return barCode;
    }

    /**
     * 渠道商品列表 不可筛选未推送
     * @author cyz
     * @date 2021/4/8 14:57
     * @param reqParam
     * @param pageParam
     * @return com.github.pagehelper.PageInfo<com.zbkj.crmeb.chant.vo.ChannelProductVo>
     */
    private PageInfo<ChannelProductVo> selectChannelProductList(ChannelProductRequest reqParam, PageParamRequest pageParam){
        PageHelper.startPage(pageParam.getPage(), pageParam.getLimit());
        //List<ChannelProductVo> channelProductList = dao.selectChannelProductList(reqParam);
        List<ChannelProductVo> channelProductList = storeProductDAO.selectNewChannelProductList(reqParam);
        // 匹配详情属性(此处应该不需要, 要的话就开启即可 author: daigb)
        // productConvertUtil.convertProduct(storeProducts);
        productConvertUtil.convertProductVoImage(channelProductList);

        channelProductList.stream().forEach(channelProductVo -> {
            QueryWrapper<ChannelProduct> qw = new QueryWrapper<>();
            qw.lambda().eq(ChannelProduct::getProductBarcode,channelProductVo.getProductBarcode());
            qw.lambda().eq(ChannelProduct::getChannelId,reqParam.getChannelId());
            ChannelProduct channelProduct = channelProductService.getOne(qw);
            //1、计算供货价
            BigDecimal supplyPrice = channelProductVo.getPrice().multiply(reqParam.getChannelMarkupRate().divide(new BigDecimal("100"))).add(channelProductVo.getPrice());
            channelProductVo.setSupplyPrice(supplyPrice);

            if(null == channelProduct){
                channelProductVo.setPushFlag(ChannelPushFlagEnum.NOT_PUSH.getCode());
                channelProductVo.setPushStatus(ChannelPushStatusEnum.NOT_PUSH.getCode());
                channelProductVo.setMarkupRate(new BigDecimal("0"));
                channelProductVo.setId(null);
                channelProductVo.setMarkupType("0");
                channelProductVo.setProductPrice(supplyPrice);
            }else {
                channelProductVo.setPushFlag(channelProduct.getPushFlag());
                channelProductVo.setPushStatus(channelProduct.getPushStatus());
                channelProductVo.setMarkupRate(channelProduct.getMarkupRate());
                channelProductVo.setId(channelProduct.getId());
                channelProductVo.setMarkupType(channelProduct.getMarkupType());
                channelProductVo.setProductPrice(channelProduct.getProductPrice());
                if(null!=channelProduct.getPushTime()){
                    channelProductVo.setPushTime(DateUtil.dateToStr(channelProduct.getPushTime(), Constants.DATE_FORMAT));
                }
            }
            channelProductVo.setChannelId(reqParam.getChannelId());
            //2、计算售价
            if(!"1".equals(channelProductVo.getMarkupType())){
                BigDecimal productPrice = supplyPrice.multiply(channelProductVo.getMarkupRate().divide(new BigDecimal("100"))).add(supplyPrice);
                channelProductVo.setProductPrice(productPrice);
            }
            //3、计算是否建议推送
            channelProductVo.setProPushFlag(false);
            if(channelProductVo.getOtPrice().compareTo(new BigDecimal("0")) > 0){
                if(supplyPrice.compareTo(new BigDecimal("5000")) >= 0 && channelProductVo.getProductPrice().multiply(new BigDecimal("1.28")).compareTo(channelProductVo.getOtPrice()) <= 0){
                    channelProductVo.setProPushFlag(true);
                }else if(supplyPrice.compareTo(new BigDecimal("5000")) < 0 && channelProductVo.getProductPrice().multiply(new BigDecimal("1.17")).compareTo(channelProductVo.getOtPrice()) <= 0){
                    channelProductVo.setProPushFlag(true);
                }
            }
        });
        return new PageInfo<>(channelProductList);
    }

    /**
     * 渠道商品列表  提供筛选推送 分页
     * @author cyz
     * @date 2021/4/8 14:57
     * @param reqParam
     * @param pageParam
     * @return com.github.pagehelper.PageInfo<com.zbkj.crmeb.chant.vo.ChannelProductVo>
     */
    private PageInfo<ChannelProductVo> selectChannelProductListByNoPush(ChannelProductRequest reqParam, PageParamRequest pageParam){
        Page page = new Page(pageParam.getPage(), pageParam.getLimit());
        List<ChannelProductVo> channelProductList = new ArrayList<>();
        if(ChannelPushFlagEnum.NOT_PUSH.getCode() == reqParam.getPushFlag()){
            reqParam.setPushFlag(null);
            channelProductList = storeProductDAO.selectNewChannelProductList(reqParam);

            reqParam.setPushFlag(ChannelPushFlagEnum.NOT_PUSH.getCode());
            List<ChannelProductVo> channelHaveProductList = storeProductDAO.selectChannelProductListByPushFlag(reqParam);
            channelProductList = channelProductList.stream().filter(item -> !channelHaveProductList.stream().map(e -> e.getProductBarcode()).collect(Collectors.toList()).contains(item.getProductBarcode())).collect(Collectors.toList());

        }else {
            channelProductList = storeProductDAO.selectChannelProductListByPushFlag(reqParam);
        }

        // 匹配详情属性(此处应该不需要, 要的话就开启即可 author: daigb)
        // productConvertUtil.convertProduct(storeProducts);
        productConvertUtil.convertProductVoImage(channelProductList);

        channelProductList.stream().forEach(channelProductVo -> {
            QueryWrapper<ChannelProduct> qw = new QueryWrapper<>();
            qw.lambda().eq(ChannelProduct::getProductBarcode,channelProductVo.getProductBarcode());
            qw.lambda().eq(ChannelProduct::getChannelId,reqParam.getChannelId());
            ChannelProduct channelProduct = channelProductService.getOne(qw);

            //1、计算供货价
            BigDecimal supplyPrice = channelProductVo.getPrice().multiply(reqParam.getChannelMarkupRate().divide(new BigDecimal("100"))).add(channelProductVo.getPrice());
            channelProductVo.setSupplyPrice(supplyPrice);

            if(null == channelProduct){
                channelProductVo.setPushFlag(ChannelPushFlagEnum.NOT_PUSH.getCode());
                channelProductVo.setPushStatus(ChannelPushStatusEnum.NOT_PUSH.getCode());
                channelProductVo.setMarkupRate(new BigDecimal("0"));
                channelProductVo.setId(null);
                channelProductVo.setMarkupType("0");
                channelProductVo.setProductPrice(supplyPrice);
            }else {
                channelProductVo.setPushFlag(channelProduct.getPushFlag());
                channelProductVo.setPushStatus(channelProduct.getPushStatus());
                channelProductVo.setMarkupRate(channelProduct.getMarkupRate());
                channelProductVo.setId(channelProduct.getId());
                channelProductVo.setMarkupType(channelProduct.getMarkupType());
                channelProductVo.setProductPrice(channelProduct.getProductPrice());
                if(null!=channelProduct.getPushTime()){
                    channelProductVo.setPushTime(DateUtil.dateToStr(channelProduct.getPushTime(), Constants.DATE_FORMAT));
                }
            }
            channelProductVo.setChannelId(reqParam.getChannelId());
            //2、计算售价
            if(!"1".equals(channelProductVo.getMarkupType())){
                BigDecimal productPrice = supplyPrice.multiply(channelProductVo.getMarkupRate().divide(new BigDecimal("100"))).add(supplyPrice);
                channelProductVo.setProductPrice(productPrice);
            }
            //3、计算是否建议推送
            channelProductVo.setProPushFlag(false);
            if(channelProductVo.getOtPrice().compareTo(new BigDecimal("0")) > 0){
                if(supplyPrice.compareTo(new BigDecimal("5000")) >= 0 && channelProductVo.getProductPrice().multiply(new BigDecimal("1.28")).compareTo(channelProductVo.getOtPrice()) <= 0){
                    channelProductVo.setProPushFlag(true);
                }else if(supplyPrice.compareTo(new BigDecimal("5000")) < 0 && channelProductVo.getProductPrice().multiply(new BigDecimal("1.17")).compareTo(channelProductVo.getOtPrice()) <= 0){
                    channelProductVo.setProPushFlag(true);
                }
            }
        });
        int total = channelProductList.size();

        int startIndex = (pageParam.getPage() - 1) * pageParam.getLimit();
        int endIndex = Math.min(startIndex + pageParam.getLimit(), total);
        if (total > startIndex) {
            //截取数据
            page.addAll(channelProductList.subList(startIndex, endIndex));
        } else if(total > 0){
            page.add(channelProductList);
        }
        page.setTotal(total);
        return new PageInfo<>(page);
    }

    /**
     * 分页查询sku
     */
    @Override
    public PageInfo<StoreProductAttrValueResponse> selectSkuPage(StoreProductSearchRequest request) {
        Page<Object> page = PageHelper.startPage(request.getPageNow(), request.getPageSize());
        List<StoreProductAttrValueResponse> storeBrandResponses = storeProductAttrValueDAO.selectSkuPage(request);

        return CommonPage.copyPageInfo(page, storeBrandResponses);
    }

    @Override
    public PageInfo<StoreProductNormKeywordResponse> pageNormKeywords(StoreProductSearchRequest request) {
        Page<Object> page = PageHelper.startPage(request.getPageNow(), request.getPageSize());
        List<StoreProductNormKeywordResponse> list = storeProductNormDAO.pageNormKeywords(request);

        return CommonPage.copyPageInfo(page, list);
    }

    /**
     * 实时更新商品
     * @param productId
     * @return
     */
    @Override
    public Object updateRealTime(Integer productId) {
        StoreProduct storeProduct = Optional.ofNullable(getById(productId)).orElse(new StoreProduct());
        if(ProductTypeEnum.IM.getCode().equals(storeProduct.getIsEurope())){
            merProductService.updateProductByNow(storeProduct);
            return getByProductId(productId);
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOtProduct(StoreProductCrmebRequest storeProductCrmebRequest, StoreProduct storeProduct, Integer stock, Integer merId) {
        List<Integer> brandIds = Arrays.asList(3039,252,2219,251,4150);
        if(ObjectUtils.isEmpty(storeProductCrmebRequest.getPrice()) || storeProductCrmebRequest.getPrice().compareTo(BigDecimal.ZERO) < 1){
            log.info("商品:{} 售价异常,不保存商品",storeProductCrmebRequest.getBarCode());
            return;
        }
        /****** 主表数据保存 *******/
        StoreProduct storeProductUpdate = new StoreProduct();
        BeanUtils.copyProperties(storeProductCrmebRequest, storeProductUpdate);
        storeProductUpdate.setStock(stock);
//        storeProductUpdate.setUpdateFlag(true);
        boolean isUpdate = null != storeProduct;
        Integer productId = 0;
        String barCode = storeProductCrmebRequest.getBarCode();
        // 查询标准商品
        String keyword = null == storeProductUpdate.getKeyword() ? "" : storeProductUpdate.getKeyword();
        if(ProductTypeEnum.IM.getCode() != storeProductCrmebRequest.getIsEurope()) {
            keyword = keyword.replaceAll(" ", "").replaceAll("\\\\", "").replaceAll("-", "").replaceAll("_", "").toUpperCase();
        }
        StoreProductNorm normProduct = storeProductNormService.getOne(Wrappers.<StoreProductNorm>lambdaQuery()
                .eq(StoreProductNorm :: getKeyword, keyword)
                .last("LIMIT 1")
        );
        // 新增标准商品
        boolean imStatus = false;
        boolean jkyStatus = false;
        if(ProductTypeEnum.IM.getCode() == storeProductCrmebRequest.getIsEurope() && !brandIds.contains(storeProductCrmebRequest.getBrandId())) {
            imStatus = true;
        }
        if(ProductTypeEnum.JKY.getCode() == storeProductCrmebRequest.getIsEurope() && brandIds.contains(storeProductCrmebRequest.getBrandId())) {
            jkyStatus = true;
        }
        if(imStatus || jkyStatus) {
            if(null == normProduct) {
                normProduct = new StoreProductNorm();
                BeanUtils.copyProperties(storeProductUpdate, normProduct);
                storeProductNormService.save(normProduct);
            } else {
                int normId = normProduct.getId();
                BeanUtils.copyProperties(storeProductUpdate, normProduct);
                normProduct.setId(normId);
                storeProductNormService.updateById(normProduct);
            }
        }
        // 使用标准商品配置
        if(null != normProduct && !imStatus && !jkyStatus) {
            // 不可绑定状态判断(该商户不匹配标准商品)
//            if(69 != merId) {
//            	convertProduct(normProduct, storeProductUpdate);
//            }
            convertProduct(normProduct, storeProductUpdate);
        }
        // 使用当前汇率
        if(null == storeProductUpdate.getExchangeRate()) {
            MoneyExchange moneyExchange = moneyExchangeService.getExchangeByName(Constants.EXCHANGE_EUR_NAME);
            String eurRate = null == moneyExchange ? PriceUtil.DEFAULT_EXCHANGE_RATE_EUR : moneyExchange.getBankConversionPri();
            storeProductUpdate.setExchangeRate(new BigDecimal(eurRate));
        }
        if (isUpdate) {
            this.update(Wrappers.<StoreProduct>lambdaUpdate()
                            .eq(StoreProduct::getId, storeProduct.getId())
                            .set(StoreProduct::getPrice, storeProductUpdate.getPrice())
                            .set(null != storeProductUpdate.getPromotePrice(), StoreProduct::getPromotePrice, storeProductUpdate.getPromotePrice())
                            .set(null != storeProductUpdate.getVipPrice(), StoreProduct::getVipPrice, storeProductUpdate.getVipPrice())
                            .set(null != storeProductUpdate.getStoreName(), StoreProduct::getStoreName, storeProductUpdate.getStoreName())
//                            .set(null != storeProductUpdate.getStoreInfo(), StoreProduct::getStoreInfo, storeProductUpdate.getStoreInfo())
//                            .set(null != storeProductUpdate.getComposition(), StoreProduct::getComposition, storeProductUpdate.getComposition())
//                            .set(null != storeProductUpdate.getDimension(), StoreProduct::getDimension, storeProductUpdate.getDimension())
                            .set(null != storeProductUpdate.getColorCode(), StoreProduct::getColorCode, storeProductUpdate.getColorCode())
                            .set(null != storeProductUpdate.getSeasonCode(), StoreProduct::getSeasonCode, storeProductUpdate.getSeasonCode())
                            .set(null != storeProductUpdate.getKeyword(), StoreProduct::getKeyword, storeProductUpdate.getKeyword())
                            .set(null != storeProductUpdate.getOtPrice(), StoreProduct::getOtPrice, storeProductUpdate.getOtPrice())
                            .set(null != storeProductUpdate.getPostage(), StoreProduct::getPostage, storeProductUpdate.getPostage())
                            .set(null != storeProductUpdate.getBrandId(), StoreProduct::getBrandId, storeProductUpdate.getBrandId())
                            .set(null != storeProductUpdate.getBrandName(), StoreProduct::getBrandName, storeProductUpdate.getBrandName())
                            .set(null != storeProductUpdate.getSuppliersId(), StoreProduct::getSuppliersId, storeProductUpdate.getSuppliersId())
                            .set(null != storeProductUpdate.getSuppliersName(), StoreProduct::getSuppliersName, storeProductUpdate.getSuppliersName())
                            .set(null != storeProductUpdate.getCateId(), StoreProduct::getCateId, storeProductUpdate.getCateId())
                            .set(null != storeProductUpdate.getGiveIntegral(), StoreProduct::getGiveIntegral, storeProductUpdate.getGiveIntegral())
                            .set(null != storeProductUpdate.getCost(), StoreProduct::getCost, storeProductUpdate.getCost())
                            .set(null != storeProductUpdate.getSourceCost(), StoreProduct::getSourceCost, storeProductUpdate.getSourceCost())
                            .set(null != storeProductUpdate.getSpecType(), StoreProduct::getSpecType, storeProductUpdate.getSpecType())
                            .set(null != storeProductUpdate.getLastPushTime(), StoreProduct::getLastPushTime, storeProductUpdate.getLastPushTime())
//                    .set(null != storeProductUpdate.getIsEurope(), StoreProduct::getIsEurope, storeProductUpdate.getIsEurope())
                            .set(null != storeProductUpdate.getTempId(), StoreProduct::getTempId, storeProductUpdate.getTempId())
                            .set(null == storeProduct.getImage(), StoreProduct::getImage, storeProductUpdate.getImage())
//                            .set(null == storeProduct.getSliderImage() || CollectionUtils.isEmpty(com.alibaba.fastjson.JSONArray.parseArray(storeProduct.getSliderImage())), StoreProduct::getSliderImage, storeProductUpdate.getSliderImage())
                            .set(StoreProduct::getNormId, storeProductUpdate.getNormId())
//                            .set(StoreProduct::getUpdateFlag, storeProductUpdate.getUpdateFlag())
                            .set(StoreProduct::getExchangeRate, storeProductUpdate.getExchangeRate())
                            .set(StoreProduct::getIsShow, true)
                            .set(StoreProduct::getStock, stock)
                            .set(null != storeProductUpdate.getCountryId(), StoreProduct::getCountryId, storeProductUpdate.getCountryId())
//                            .set(null != storeProductUpdate.getWeight(), StoreProduct::getWeight, storeProductUpdate.getWeight())
//                            .set(null != storeProductUpdate.getProductionPlace(), StoreProduct::getProductionPlace, storeProductUpdate.getProductionPlace())
//                    .set(StoreProduct::getTmall, storeProductUpdate.getTmall())
            );
            productId = storeProduct.getId();
            barCode = storeProduct.getBarCode();
        } else {
            //表格导入
            storeProductUpdate.setCommodityType(2);
            storeProductUpdate.setCreateTime(new Date());
            this.save(storeProductUpdate);
            productId = storeProductUpdate.getId();
            //自动下架
            List<ChannelMerchant> merchantList = channelMerchantService.list(Wrappers.<ChannelMerchant>lambdaQuery().eq(ChannelMerchant::getIsDel, 0).eq(ChannelMerchant::getAutomaticShelves, 0).select(ChannelMerchant::getId));
            merchantList.forEach(mer->{
                MybatisPlusConfig.tableNameMp.set(TableNameUtil.getProductMerName(mer.getId()));
                StoreProductMer storeMerProduct = storeProductMerService.getOne(Wrappers.<StoreProductMer>lambdaQuery()
                        .eq(StoreProductMer :: getProductId, storeProductUpdate.getId())
                        .last("LIMIT 1"));
                if(null == storeMerProduct) {
                    storeMerProduct = new StoreProductMer();
                    storeMerProduct.setProductId(storeProductUpdate.getId());
                    storeMerProduct.setIsNotShow("1");
                    storeMerProduct.setIsSystemOut(1);
                    storeMerProduct.setCreateTime(new Date());
                    storeMerProduct.setUpdateTime(new Date());
                    MybatisPlusConfig.tableNameMp.set(TableNameUtil.getProductMerName(mer.getId()));
                    storeProductMerService.save(storeMerProduct);
                }
            });
        }
        /****** attr表保存 ********/
        if (isUpdate) {
            storeProductAttrService.removeByProductId(productId);
        }
        List<StoreProductAttr> attrs = storeProductCrmebRequest.getAttr();
        for (StoreProductAttr attr : attrs) {
            attr.setProductId(productId);
            attr.setBarCode(barCode);
            attr.setAttrValues(StringUtils.strip(attr.getAttrValues().replace("\"", ""), "[]"));
        }
        storeProductAttrService.saveBatch(attrs);
        /****** value表保存 *********/
//        Map<String, StoreProductAttrValue> dbStoreProductAttrValueMap = new HashMap<>();
        if (isUpdate) {
//            List<StoreProductAttrValue> dbStoreProductAttrValues = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery().eq(StoreProductAttrValue::getProductId, productId));
//            dbStoreProductAttrValueMap = dbStoreProductAttrValues.stream().collect(Collectors.toMap(StoreProductAttrValue::getSourceSkuId, s -> s, (value1, value2) -> {
//                return value1;
//            }));
            // 删除所有value
            storeProductAttrValueService.removeByProductId(productId);
        }
        List<StoreProductAttrValueRequest> storeProductAttrValuesRequest = storeProductCrmebRequest.getAttrValue();
        List<StoreProductAttrValue> values = new ArrayList<>();
        for (StoreProductAttrValueRequest attrValuesRequest : storeProductAttrValuesRequest) {
            attrValuesRequest.setProductId(productId);
            attrValuesRequest.setBarCode(barCode);
            attrValuesRequest.setSourceSkuId(storeProductCrmebRequest.getIsEurope()+"-"+attrValuesRequest.getSourceSkuId());
            StoreProductAttrValue spav = new StoreProductAttrValue();
            BeanUtils.copyProperties(attrValuesRequest, spav);
            List<String> skuList = new ArrayList<>();
            for (Map.Entry<String, String> vo : attrValuesRequest.getAttrValue().entrySet()) {
                skuList.add(vo.getValue());
                spav.setSuk(String.join(",", skuList));
            }
            spav.setAttrValue(JSON.toJSONString(attrValuesRequest.getAttrValue()));
//            StoreProductAttrValue tempValue = dbStoreProductAttrValueMap.get(spav.getSourceSkuId());
//            if (null != tempValue) {
//                spav.setId(tempValue.getId());
//            }
            values.add(spav);
        }
        storeProductAttrValueService.saveBatch(values);
        /****** result表保存 ******/
        if (isUpdate) {
            storeProductAttrResultService.remove(Wrappers.<StoreProductAttrResult>lambdaQuery().eq(StoreProductAttrResult::getProductId, productId));
        }
        StoreProductAttrResult attrResult = new StoreProductAttrResult(/*0,*/ productId, systemAttachmentService.clearPrefix(JSON.toJSONString(storeProductCrmebRequest.getAttrValue())), Integer.parseInt(String.valueOf(System.currentTimeMillis() / 1000L)), Constants.PRODUCT_TYPE_NORMAL, barCode);
        storeProductAttrResultService.save(attrResult);

        /****** Description表保存 ******/
        StoreProductDescription dbDescription = storeProductDescriptionService.getOne(Wrappers.<StoreProductDescription>lambdaQuery()
        		.eq(StoreProductDescription :: getProductId, productId)
        		.last("LIMIT 1")
        		);
        StoreProductDescription storeProductDescription = StoreProductDescription.getDescriptionByCrmeb(storeProductCrmebRequest);
        storeProductDescription.setId(ObjectUtil.isNotNull(dbDescription) ? dbDescription.getId() : null);
        storeProductDescription.setProductId(productId);
        storeProductDescriptionService.saveOrUpdate(storeProductDescription);

    }

    @Override
    public boolean auditTransferCloud(BestEnabledRequest vo) {
        List<StoreProduct> productList = this.list(Wrappers.<StoreProduct>lambdaQuery().in(StoreProduct::getId, vo.getProductIdList())
                .select(StoreProduct::getId, StoreProduct::getSelfPushStatus, StoreProduct::getPushChangeTime,StoreProduct::getMerId,
                        StoreProduct::getCost,StoreProduct::getPrice));
        if (CollectionUtils.isEmpty(productList)) {
            throw new CrmebException("商品不存在");
        }
        if (productList.stream().anyMatch(e -> !Objects.equals(e.getSelfPushStatus(), 1))) {
            throw new CrmebException("所选商品存在不是审核中状态的商品");
        }
        List<Integer> merIdList = productList.stream().map(StoreProduct::getMerId).distinct().collect(Collectors.toList());
        List<Supplier> supplierList = supplierService.list(Wrappers.<Supplier>lambdaQuery().in(Supplier::getMerId, merIdList));
        for (Supplier supplier : supplierList) {
            if(supplier.getIsEurope() == null){
                throw new CrmebException("请先设置商户"+supplier.getMerId()+"is_europe属性");
            }
        }
        Map<Integer, Integer> map = supplierList.stream().collect(Collectors.toMap(Supplier::getMerId, Supplier::getIsEurope));
        List<Integer> productIdList = productList.stream().map(StoreProduct::getId).collect(Collectors.toList());
        for (StoreProduct storeProduct : productList) {
            storeProduct.setPushChangeTime(new Date());
            storeProduct.setSelfPushStatus(vo.getIsBest() ? 2 : 3);
            if(vo.getIsBest()){
                storeProduct.setConvertIsEurope(map.get(storeProduct.getMerId()));
                storeProduct.setCommodityType(3);
            }
            //供货价转成本价
            storeProduct.setSourceCost(storeProduct.getCost());
        }
        //处理sku成本价
        storeProductAttrValueService.updateValueSourceCost(productIdList);
        return this.updateBatchById(productList);
    }

    @Override
    public List<Integer> getIsShowProducts(List<Integer> productIdList, Integer merId) {
        List<Integer> list = new ArrayList<>();
        if(CollectionUtils.isEmpty(productIdList)){
            return list;
        }
        ChannelMerchant channelMerchant = channelMerchantService.getChannelMerchantByMerId(merId);
        //可见配置
        List<Integer> brandIdsList= JSON.parseArray(channelMerchant.getBrandIds(), Integer.class);
        List<Integer> suppliersIdList = JSON.parseArray(channelMerchant.getSuppliersIds(), Integer.class);
        List<Integer> tempIdList = JSON.parseArray(channelMerchant.getTempId(), Integer.class);
        if (CollectionUtils.isNotEmpty(suppliersIdList)) {
            Supplier supplier = supplierService.getSupplierBarcode(merId);
            if (null != supplier) {
                suppliersIdList.add(supplier.getId());
            }
        }
        //不可见分类
        List<Integer> cateIdList = categoryMatchService.selectCategoryMatchDisable(merId).stream().map(CategoryMatch::getId).collect(Collectors.toList());
        //查询
        LambdaQueryWrapper<StoreProduct> lambdaQueryWrapper = Wrappers.<StoreProduct>lambdaQuery()
                .eq(StoreProduct::getIsShow,1)
                .eq(StoreProduct::getIsDel,0)
                .gt(StoreProduct::getStock,0);
        if(CollectionUtils.isNotEmpty(brandIdsList)){
            lambdaQueryWrapper.in(StoreProduct::getBrandId,brandIdsList);
        }
        if(CollectionUtils.isNotEmpty(suppliersIdList)){
            lambdaQueryWrapper.in(StoreProduct::getSuppliersId,suppliersIdList);
        }
        if(CollectionUtils.isNotEmpty(tempIdList)){
            lambdaQueryWrapper.in(StoreProduct::getTempId,tempIdList);
        }
        if(CollectionUtils.isNotEmpty(cateIdList)){
            lambdaQueryWrapper.notIn(StoreProduct::getCateId,cateIdList);
        }
        lambdaQueryWrapper.in(StoreProduct::getId,productIdList);
        lambdaQueryWrapper.notInSql(StoreProduct::getId, "SELECT product_id FROM " + TableNameUtil.getProductMerName(merId) + " WHERE is_not_show = 1");
        lambdaQueryWrapper.select(StoreProduct::getId);
        List<StoreProduct> productList = this.list(lambdaQueryWrapper);
        if(CollectionUtils.isEmpty(productList)){
            return list;
        }
        return productList.stream().map(StoreProduct::getId).collect(Collectors.toList());
    }

    @Override
    public boolean batchAssociateNormProduct(BatchAssociateNormProductRequest request) {
        if(request.getProductId() != null){
            StoreProduct storeProduct = this.getById(request.getProductId());
            // 匹配详情属性
            productConvertUtil.convertProduct(storeProduct);
            StoreProductNorm storeProductNorm = new StoreProductNorm();
            StoreProductNorm norm = storeProductNormDAO.selectOne(Wrappers.<StoreProductNorm>lambdaQuery()
                    .eq(StoreProductNorm :: getKeyword, storeProduct.getKeyword())
                    .last("LIMIT 1")
            );
            BeanUtils.copyProperties(storeProduct, storeProductNorm);
            storeProductNorm.setId(null);
            if(null != norm) {
                storeProductNorm.setId(norm.getId());
            }
            storeProductNormService.saveOrUpdate(storeProductNorm);
            return this.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .in(StoreProduct :: getId, request.getProductIdList())
                    .set(StoreProduct :: getStoreName, storeProductNorm.getStoreName())
                    .set(StoreProduct :: getColorCode, storeProductNorm.getColorCode())
                    .set(StoreProduct :: getSeasonCode, storeProductNorm.getSeasonCode())
                    .set(StoreProduct :: getBrandId, storeProductNorm.getBrandId())
                    .set(StoreProduct :: getBrandName, storeProductNorm.getBrandName())
                    .set(StoreProduct :: getCateId, storeProductNorm.getCateId())
                    .set(StoreProduct :: getNormId, storeProductNorm.getId())
            );
        }else if(request.getNormId() != null){
            StoreProductNorm productNorm = storeProductNormService.getById(request.getNormId());
            if(productNorm == null){
                throw new CrmebException("该标准商品不存在");
            }
            return this.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .in(StoreProduct :: getId, request.getProductIdList())
                    .set(StoreProduct :: getStoreName, productNorm.getStoreName())
                    .set(StoreProduct :: getColorCode, productNorm.getColorCode())
                    .set(StoreProduct :: getSeasonCode, productNorm.getSeasonCode())
                    .set(StoreProduct :: getBrandId, productNorm.getBrandId())
                    .set(StoreProduct :: getBrandName, productNorm.getBrandName())
                    .set(StoreProduct :: getCateId, productNorm.getCateId())
                    .set(StoreProduct :: getNormId, productNorm.getId())
            );
        }
        return false;
    }

    // 每隔12小时执行一次清理任务
    @Scheduled(fixedRate = 12 * 60 * 60 * 1000) // 12小时
    @CacheEvict(value = "brandsIdList", allEntries = true)
    public void cleanupCache() {
        log.info("====》12小时, 开始清理 brandsIdList缓存数据...");
    }

    /**
     * 获取供应商商品对应的品牌
     * @param merId 商户id
     * @return
     */
    @Override
    @Cacheable("brandsIdList")
    public List<Integer> getBrandsByMerId(Integer merId, String cateId) {
        // 商户信息
        ChannelMerchant channelMerchant = channelMerchantService.getChannelMerchantByMerId(merId);
        List<Integer> merBrandIdList = new ArrayList<>();
        // 设置了可见品牌
        com.alibaba.fastjson.JSONArray brandIds = JSON.parseArray(channelMerchant.getBrandIds());
        if (CollectionUtils.isEmpty(brandIds)) {
            // 可见供应商
            List<Integer> suppliersIdList = JSON.parseArray(channelMerchant.getSuppliersIds(), Integer.class);
            List<Integer> tempIdList = JSON.parseArray(channelMerchant.getTempId(), Integer.class);
            // 不可见分类
            List<Integer> cateIds = categoryMatchService.selectCategoryMatchDisable(merId).stream().map(CategoryMatch::getId).collect(Collectors.toList());
            // 当前搜索分类
            List<Integer> categoryIdList = new ArrayList<>();
            if (StringUtils.isNotBlank(cateId)) {
                String[] cateIdStrs = cateId.split(",");
                for (String id : cateIdStrs) {
                    List<Integer> childIdList = categoryMatchService.getThreeChildVoListByPid(Integer.parseInt(id)).stream().map(CategoryMatch::getId).collect(Collectors.toList());
                    categoryIdList.addAll(childIdList);
                }
            }
            // 商户对应自建供应商
            Supplier supplier = supplierService.getSupplierBarcode(merId);


            // 查询商户可见供应商商品所有的品牌
            List<StoreProduct> storeProducts = list(Wrappers.lambdaQuery(StoreProduct.class).eq(StoreProduct::getIsDel, 0)
                    .eq(StoreProduct::getIsShow, 1)
                    .gt(StoreProduct::getStock, 0)
                    .notInSql(StoreProduct::getId, "SELECT product_id FROM " + TableNameUtil.getProductMerName(merId) + " WHERE is_not_show = 1")
                    .in(CollectionUtils.isNotEmpty(suppliersIdList), StoreProduct::getSuppliersId, suppliersIdList)
                    .in(CollectionUtils.isNotEmpty(tempIdList), StoreProduct::getTempId, tempIdList)
                    .in(CollectionUtils.isNotEmpty(categoryIdList), StoreProduct::getCateId, categoryIdList)
                    .and(qr -> qr.eq(StoreProduct::getSuppliersId, Objects.nonNull(supplier) ? supplier.getId() : 0)
                            .or(e -> e.in(CollectionUtils.isNotEmpty(suppliersIdList), StoreProduct::getSuppliersId, suppliersIdList)
                                    .and(i -> i.ne(StoreProduct::getIsEurope, ProductTypeEnum.INSIDE)
                                    .or(a -> a.eq(StoreProduct::getIsEurope, ProductTypeEnum.INSIDE).isNotNull(StoreProduct::getConvertIsEurope)))))
                    .notIn(CollectionUtils.isNotEmpty(cateIds), StoreProduct::getCateId, cateIds)
                    .groupBy(StoreProduct::getBrandId)
                    .select(StoreProduct::getBrandId));

            for (StoreProduct product : storeProducts){
                StoreBrand brand = storeBrandService.getById(product.getBrandId());
                if(brand != null && brand.getProductCount() > 0){
                    merBrandIdList.add(brand.getId());
                }
            }

            /*merBrandIdList = this.baseMapper.selectBrandIds(TableNameUtil.getProductMerName(merId), suppliersIdList, tempIdList, categoryIdList,
                    Objects.nonNull(supplier)?supplier.getId() : 0, cateIds);*/

        } else {
            merBrandIdList = brandIds.toJavaList(Integer.class);
        }

        return  merBrandIdList;
    }

    private void convertProduct(StoreProductNorm sourceProduct, StoreProduct targetProduct) {
        if(StringUtil.isNotEmpty(sourceProduct.getStoreName())) {
            targetProduct.setStoreName(sourceProduct.getStoreName());
        }
        if(StringUtil.isNotEmpty(sourceProduct.getStoreInfo())) {
            targetProduct.setStoreInfo(sourceProduct.getStoreInfo());
        }
        if(StringUtil.isNotEmpty(sourceProduct.getComposition())) {
            targetProduct.setComposition(sourceProduct.getComposition());
        }
        if(StringUtil.isNotEmpty(sourceProduct.getDimension())) {
            targetProduct.setDimension(sourceProduct.getDimension());
        }
        if(StringUtil.isNotEmpty(sourceProduct.getColorCode())) {
            targetProduct.setColorCode(sourceProduct.getColorCode());
        }
        if(StringUtil.isNotEmpty(sourceProduct.getSeasonCode())) {
            targetProduct.setSeasonCode(sourceProduct.getSeasonCode());
        }
//        if(StringUtil.isNotEmpty(sourceProduct.getImage())) {
//            targetProduct.setImage(sourceProduct.getImage());
//        }
//        if(StringUtil.isNotEmpty(sourceProduct.getSliderImage())) {
//            targetProduct.setSliderImage(sourceProduct.getSliderImage());
//        }
        if(null != sourceProduct.getBrandId()) {
            targetProduct.setBrandId(sourceProduct.getBrandId());
        }
        if(null != sourceProduct.getBrandName()) {
            targetProduct.setBrandName(sourceProduct.getBrandName());
        }
        if(null != sourceProduct.getCateId()) {
            targetProduct.setCateId(sourceProduct.getCateId());
        }
        targetProduct.setNormId(sourceProduct.getId());
    }

}
